diff --git a/apps/emqx_modules/src/emqx_modules_schema.erl b/apps/emqx_modules/src/emqx_modules_schema.erl index 5eb8ca148..891e0a076 100644 --- a/apps/emqx_modules/src/emqx_modules_schema.erl +++ b/apps/emqx_modules/src/emqx_modules_schema.erl @@ -36,6 +36,7 @@ roots() -> array("rewrite", #{ desc => "List of topic rewrite rules.", importance => ?IMPORTANCE_HIDDEN, + validator => fun rewrite_validator/1, default => [] }), array("topic_metrics", #{ @@ -45,6 +46,37 @@ roots() -> }) ]. +rewrite_validator(Rules) -> + case + lists:foldl( + fun + (#{<<"action">> := subscribe}, Acc) -> + Acc; + (#{<<"dest_topic">> := DestTopic}, InvalidAcc) -> + try + true = emqx_topic:validate(name, DestTopic), + InvalidAcc + catch + _:_ -> + [DestTopic | InvalidAcc] + end + end, + [], + Rules + ) + of + [] -> + ok; + InvalidTopics -> + { + error, + #{ + msg => "cannot_use_wildcard_for_destination_topic", + invalid_topics => InvalidTopics + } + } + end. + fields("delayed") -> [ {enable, ?HOCON(boolean(), #{default => true, desc => ?DESC(enable)})}, diff --git a/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl b/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl index 528102d9e..6c65d351b 100644 --- a/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl +++ b/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl @@ -95,6 +95,52 @@ t_mqtt_topic_rewrite_limit(_) -> ) ). +t_mqtt_topic_rewrite_wildcard(_) -> + BadRules = [ + #{ + <<"source_topic">> => <<"test/#">>, + <<"re">> => <<"^test/(.+)$">>, + <<"dest_topic">> => <<"bad/test/#">> + }, + #{ + <<"source_topic">> => <<"test/#">>, + <<"re">> => <<"^test/(.+)$">>, + <<"dest_topic">> => <<"bad/#/test">> + }, + #{ + <<"source_topic">> => <<"test/#">>, + <<"re">> => <<"^test/(.+)$">>, + <<"dest_topic">> => <<"bad/test/+">> + }, + #{ + <<"source_topic">> => <<"test/#">>, + <<"re">> => <<"^test/(.+)$">>, + <<"dest_topic">> => <<"bad/+/test">> + } + ], + + Rules = lists:flatten( + lists:map( + fun(Rule) -> + [Rule#{<<"action">> => <<"publish">>}, Rule#{<<"action">> => <<"all">>}] + end, + BadRules + ) + ), + lists:foreach( + fun(Rule) -> + ?assertMatch( + {ok, 500, _}, + request( + put, + uri(["mqtt", "topic_rewrite"]), + [Rule] + ) + ) + end, + Rules + ). + %%------------------------------------------------------------------------------ %% Helpers %%------------------------------------------------------------------------------ diff --git a/changes/ce/fix-11004.en.md b/changes/ce/fix-11004.en.md new file mode 100644 index 000000000..3c6b580d7 --- /dev/null +++ b/changes/ce/fix-11004.en.md @@ -0,0 +1 @@ +Do not allow wildcards for destination topic in rewrite rules.