From b0b4518228a064bc1012a7d6dcb27ba0e62af243 Mon Sep 17 00:00:00 2001 From: Francesco Zanitti Date: Tue, 9 Jul 2019 21:51:19 +0200 Subject: [PATCH 1/3] filter out non-normalizing uris --- src/broen_core.erl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/broen_core.erl b/src/broen_core.erl index 06021b0..f2b48a6 100644 --- a/src/broen_core.erl +++ b/src/broen_core.erl @@ -277,7 +277,17 @@ valid_route([]) -> false; valid_route(Paths) -> Sum = lists:foldl(fun(El, Sum) -> Sum + byte_size(El) end, 0, Paths), - Sum =< 255. + (Sum =< 255) and valid_uri(Paths). + +valid_uri(Paths) -> + Path = iolist_to_binary(lists:join(<<"/">>, Paths)), + case uri_string:normalize(#{path => Path}) of + {error, Kind, Cause} -> + lager:warning("invalid uri ~p ~p~n", [Kind, Cause]), + false; + _Normalized -> + true + end. %% '.' is converted to '_' iff the keep_dots_in_routing_key is false, %% otherwise it is left as a '.' From 64da25ce938d75d2bbd810f11e36a1003799ab95 Mon Sep 17 00:00:00 2001 From: Francesco Zanitti Date: Tue, 9 Jul 2019 21:54:05 +0200 Subject: [PATCH 2/3] bumped vsn --- src/broen.app.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/broen.app.src b/src/broen.app.src index 9e8edd6..6a7754e 100644 --- a/src/broen.app.src +++ b/src/broen.app.src @@ -1,7 +1,7 @@ {application, broen, [ {description, "broen provides a bridge between HTTP and AMQP"}, - {vsn, "2.2.6"}, + {vsn, "2.2.7"}, {registered, []}, {applications, [ kernel, From fe434f1f6ae131046bc386b3cbb14ca578f20a1b Mon Sep 17 00:00:00 2001 From: Francesco Zanitti Date: Wed, 10 Jul 2019 10:32:05 +0200 Subject: [PATCH 3/3] use other method to check uri validity --- src/broen_core.erl | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/broen_core.erl b/src/broen_core.erl index f2b48a6..c334c5e 100644 --- a/src/broen_core.erl +++ b/src/broen_core.erl @@ -279,15 +279,30 @@ valid_route(Paths) -> Sum = lists:foldl(fun(El, Sum) -> Sum + byte_size(El) end, 0, Paths), (Sum =< 255) and valid_uri(Paths). +%% check that all path tokens are printable (filter requests with control +%% characters) and valid utf8 strings valid_uri(Paths) -> - Path = iolist_to_binary(lists:join(<<"/">>, Paths)), - case uri_string:normalize(#{path => Path}) of - {error, Kind, Cause} -> - lager:warning("invalid uri ~p ~p~n", [Kind, Cause]), - false; - _Normalized -> - true - end. + Printable = fun (T) -> + case io_lib:printable_unicode_list(binary_to_list(T)) of + true -> true; + false -> + lager:warning("Non-printable path segment: ~p", [T]), + false + end + end, + ValidUtf8 = fun (T) -> + case unicode:characters_to_binary(T, utf8, utf8) of + Res when is_binary(Res) -> true; + Other -> + lager:warning("Invalid path segment encoding: ~p (~p)", [T, Other]), + false + end + end, + + CheckFun = fun (T) -> + ValidUtf8(T) and Printable(T) + end, + lists:all(CheckFun, Paths). %% '.' is converted to '_' iff the keep_dots_in_routing_key is false, %% otherwise it is left as a '.'