ソースを参照

fix: restrict client_attr key and value string format

The keys and values are used to render templates for
authz rules, such as topic names, and SQL statements etc.
zmstone 1 年間 前
コミット
c75840306b

+ 11 - 1
apps/emqx_auth/src/emqx_authn/emqx_authn_utils.erl

@@ -207,10 +207,20 @@ is_superuser(#{}) ->
     #{is_superuser => false}.
 
 client_attrs(#{<<"client_attrs">> := Attrs}) ->
-    #{client_attrs => Attrs};
+    #{client_attrs => drop_invalid_attr(Attrs)};
 client_attrs(_) ->
     #{client_attrs => #{}}.
 
+drop_invalid_attr(Map) when is_map(Map) ->
+    maps:from_list(do_drop_invalid_attr(maps:to_list(Map))).
+
+do_drop_invalid_attr(KVL) ->
+    F = fun({K, V}) ->
+        emqx_utils:is_restricted_str(K) andalso
+            emqx_utils:is_restricted_str(V)
+    end,
+    lists:filter(F, KVL).
+
 ensure_apps_started(bcrypt) ->
     {ok, _} = application:ensure_all_started(bcrypt),
     ok;

+ 10 - 2
apps/emqx_auth_http/test/emqx_authn_http_SUITE.erl

@@ -542,13 +542,21 @@ samples() ->
                 Req = cowboy_req:reply(
                     200,
                     #{<<"content-type">> => <<"application/json">>},
-                    emqx_utils_json:encode(#{result => allow, is_superuser => true}),
+                    emqx_utils_json:encode(#{
+                        result => allow,
+                        is_superuser => true,
+                        client_attrs => #{
+                            fid => <<"n11">>,
+                            <<"_bad_key">> => <<"v">>,
+                            <<"ok_key">> => <<"but bad value">>
+                        }
+                    }),
                     Req0
                 ),
                 {ok, Req, State}
             end,
             config_params => #{},
-            result => {ok, #{is_superuser => true, client_attrs => #{}}}
+            result => {ok, #{is_superuser => true, client_attrs => #{<<"fid">> => <<"n11">>}}}
         },
 
         %% get request with url-form-encoded body response

+ 9 - 1
apps/emqx_utils/src/emqx_utils.erl

@@ -67,7 +67,8 @@
     format/1,
     call_first_defined/1,
     ntoa/1,
-    foldl_while/3
+    foldl_while/3,
+    is_restricted_str/1
 ]).
 
 -export([
@@ -861,6 +862,13 @@ ntoa({0, 0, 0, 0, 0, 16#ffff, AB, CD}) ->
 ntoa(IP) ->
     inet_parse:ntoa(IP).
 
+%% @doc Return true if the provided string is a restricted string:
+%% Start with a letter or a digit,
+%% remaining characters can be '-' or '_' in addition to letters and digits
+is_restricted_str(String) ->
+    RE = <<"^[A-Za-z0-9]+[A-Za-z0-9-_]*$">>,
+    match =:= re:run(String, RE, [{capture, none}]).
+
 -ifdef(TEST).
 -include_lib("eunit/include/eunit.hrl").