Skip to content

Commit 39c3a8e

Browse files
Management plugin: apply path filtering earlier
Before `cowboy_static` has a chance to run.
1 parent 4e11945 commit 39c3a8e

1 file changed

Lines changed: 40 additions & 7 deletions

File tree

deps/rabbitmq_management/src/rabbit_mgmt_wm_static.erl

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,51 @@ init(Req0, [{App, Path}]) ->
3333
init(Req0, [{App, Path}|Tail]) ->
3434
Req1 = rabbit_mgmt_headers:set_common_permission_headers(Req0, ?MODULE),
3535
PathInfo = cowboy_req:path_info(Req1),
36-
Filepath = filename:join([code:priv_dir(App), Path|PathInfo]),
37-
%% We use erl_prim_loader because the file may be inside an .ez archive.
38-
FileInfo = erl_prim_loader:read_file_info(binary_to_list(Filepath)),
39-
case FileInfo of
40-
{ok, #file_info{type = regular}} -> do_init(Req1, App, Path);
41-
{ok, #file_info{type = symlink}} -> do_init(Req1, App, Path);
42-
_ -> init(Req0, Tail)
36+
case validate_path_info(PathInfo) of
37+
ok ->
38+
Filepath = filename:join([code:priv_dir(App), Path|PathInfo]),
39+
%% We use `erl_prim_loader` because the file may be inside
40+
%% an .ez archive.
41+
FileInfo = erl_prim_loader:read_file_info(
42+
binary_to_list(Filepath)),
43+
case FileInfo of
44+
{ok, #file_info{type = regular}} ->
45+
do_init(Req1, App, Path);
46+
{ok, #file_info{type = symlink}} ->
47+
do_init(Req1, App, Path);
48+
_ ->
49+
init(Req0, Tail)
50+
end;
51+
error ->
52+
init(Req0, Tail)
4353
end.
4454

4555
do_init(Req, App, Path) ->
4656
cowboy_static:init(Req, {priv_dir, App, Path}).
4757

58+
%% Must be done here before `erl_prim_loader:read_file_info/1`
59+
%% is used.
60+
%%
61+
%% This mirrors the validation that `cowboy_static` performs internally
62+
%% except that this validation must happen before the one in Cowboy.
63+
validate_path_info([]) ->
64+
ok;
65+
validate_path_info([<<".">>|_]) ->
66+
error;
67+
validate_path_info([<<"..">>|_]) ->
68+
error;
69+
validate_path_info([Segment|Tail]) ->
70+
case validate_segment(Segment) of
71+
ok -> validate_path_info(Tail);
72+
error -> error
73+
end.
74+
75+
validate_segment(Segment) ->
76+
case binary:match(Segment, [<<$/>>, <<$\\>>, <<0>>]) of
77+
nomatch -> ok;
78+
_ -> error
79+
end.
80+
4881
malformed_request(Req, State) ->
4982
cowboy_static:malformed_request(Req, State).
5083

0 commit comments

Comments
 (0)