From d485f8fe964eb269642ed88264a954349fdc95d6 Mon Sep 17 00:00:00 2001 From: firest Date: Sat, 24 Jun 2023 09:10:02 +0000 Subject: [PATCH 1/3] fix: mask the value of the authorization header whatever its case --- apps/emqx_utils/src/emqx_utils.erl | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/emqx_utils/src/emqx_utils.erl b/apps/emqx_utils/src/emqx_utils.erl index 830845b60..b57b13e7d 100644 --- a/apps/emqx_utils/src/emqx_utils.erl +++ b/apps/emqx_utils/src/emqx_utils.erl @@ -616,9 +616,6 @@ try_to_existing_atom(Convert, Data, Encoding) -> _:Reason -> {error, Reason} end. -is_sensitive_key(authorization) -> true; -is_sensitive_key("authorization") -> true; -is_sensitive_key(<<"authorization">>) -> true; is_sensitive_key(aws_secret_access_key) -> true; is_sensitive_key("aws_secret_access_key") -> true; is_sensitive_key(<<"aws_secret_access_key">>) -> true; @@ -643,6 +640,12 @@ is_sensitive_key(<<"token">>) -> true; is_sensitive_key(jwt) -> true; is_sensitive_key("jwt") -> true; is_sensitive_key(<<"jwt">>) -> true; +is_sensitive_key(authorization) -> true; +is_sensitive_key("authorization") -> true; +is_sensitive_key(<<"authorization">>) -> true; +%% the authorization header is not case-sensitive +is_sensitive_key("a" ++ _ = Key) -> is_authorization(Key); +is_sensitive_key(<<"a", _/binary>> = Key) -> is_authorization(erlang:binary_to_list(Key)); is_sensitive_key(_) -> false. redact(Term) -> @@ -707,6 +710,9 @@ do_is_redacted(K, <>, Fun) -> do_is_redacted(_K, _V, _Fun) -> false. +is_authorization(Str) -> + "authorization" == string:to_lower(Str). + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -777,6 +783,23 @@ redact2_test_() -> Keys = [secret, passcode], [{case_name(atom, Key), fun() -> Case(Key, Checker) end} || Key <- Keys]. +redact_is_authorization() -> + Types = [string, binary], + Keys = ["auThorization", "Authorization", "authorizaTion"], + + Case = fun(Type, Key0) -> + Key = + case Type of + binary -> + erlang:list_to_binary(Key0); + _ -> + Key0 + end, + ?assert(is_sensitive_key(Key)) + end, + + [{case_name(Type, Key), fun() -> Case(Type, Key) end} || Key <- Keys, Type <- Types]. + case_name(Type, Key) -> lists:concat([Type, "-", Key]). From 1e140f77a7de3f521dcf93efc542c86fecbf4f8f Mon Sep 17 00:00:00 2001 From: firest Date: Sat, 24 Jun 2023 09:30:39 +0000 Subject: [PATCH 2/3] chore: update changes --- changes/ce/fix-11134.en.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/ce/fix-11134.en.md diff --git a/changes/ce/fix-11134.en.md b/changes/ce/fix-11134.en.md new file mode 100644 index 000000000..4f195c537 --- /dev/null +++ b/changes/ce/fix-11134.en.md @@ -0,0 +1 @@ +Fix the value of the uppercase `authorization` header is not obfuscated. From 31e914f6a29489387a380ca2777a8e6c92aaedb5 Mon Sep 17 00:00:00 2001 From: firest Date: Thu, 29 Jun 2023 15:57:48 +0800 Subject: [PATCH 3/3] fix(emqx_utils): improve the checking for the `authorization` key --- apps/emqx_utils/src/emqx_utils.erl | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/apps/emqx_utils/src/emqx_utils.erl b/apps/emqx_utils/src/emqx_utils.erl index b57b13e7d..86667063c 100644 --- a/apps/emqx_utils/src/emqx_utils.erl +++ b/apps/emqx_utils/src/emqx_utils.erl @@ -643,10 +643,7 @@ is_sensitive_key(<<"jwt">>) -> true; is_sensitive_key(authorization) -> true; is_sensitive_key("authorization") -> true; is_sensitive_key(<<"authorization">>) -> true; -%% the authorization header is not case-sensitive -is_sensitive_key("a" ++ _ = Key) -> is_authorization(Key); -is_sensitive_key(<<"a", _/binary>> = Key) -> is_authorization(erlang:binary_to_list(Key)); -is_sensitive_key(_) -> false. +is_sensitive_key(Key) -> is_authorization(Key). redact(Term) -> do_redact(Term, fun is_sensitive_key/1). @@ -710,7 +707,17 @@ do_is_redacted(K, <>, Fun) -> do_is_redacted(_K, _V, _Fun) -> false. -is_authorization(Str) -> +%% This is ugly, however, the authorization is case-insensitive, +%% the best way is to check chars one by one and quickly exit when any position is not equal, +%% but in Erlang, this may not perform well, so here only check the first one +is_authorization([Cap | _] = Key) when Cap == $a; Cap == $A -> + is_authorization2(Key); +is_authorization(<> = Key) when Cap == $a; Cap == $A -> + is_authorization2(erlang:binary_to_list(Key)); +is_authorization(_Any) -> + false. + +is_authorization2(Str) -> "authorization" == string:to_lower(Str). -ifdef(TEST). @@ -783,7 +790,7 @@ redact2_test_() -> Keys = [secret, passcode], [{case_name(atom, Key), fun() -> Case(Key, Checker) end} || Key <- Keys]. -redact_is_authorization() -> +redact_is_authorization_test_() -> Types = [string, binary], Keys = ["auThorization", "Authorization", "authorizaTion"],