1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
From: Steve Vinoski <vinoski@ieee.org>
Date: Sun, 6 Sep 2020 10:23:56 -0400
Subject: Sanitize CGI requests
Origin: https://github.com/erlyaws/yaws/commit/799b3b526d15b7a9bc43ae97165aeb085f18fac1
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-24916
To prevent command injection via CGI requests, disallow suspicious
shell characters in CGI executable names. Add a new test to verify
suspicious CGI requests are rejected.
[Salvatore Bonaccorso: Drop patching of testsuite as 2.0.6+dfsg import did not
contain it]
src/yaws_cgi.erl | 37 ++++++++++++++++++++++++-------------
testsuite/main_SUITE.erl | 25 +++++++++++++++++++++++++
2 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/src/yaws_cgi.erl b/src/yaws_cgi.erl
index 2732830beece..cd27b0d290c5 100644
@@ -520,11 +520,19 @@ call_cgi(Arg, Exefilename, Scriptfilename, Pathinfo, ExtraEnv) ->
exit(normal)
end;
_ ->
- WorkerPid = cgi_start_worker(Arg, Exefilename, Scriptfilename,
- Pathinfo, ExtraEnv, get(sc)),
- handle_clidata(Arg, WorkerPid)
+ case cgi_start_worker(Arg, Exefilename, Scriptfilename,
+ Pathinfo, ExtraEnv, get(sc)) of
+ {ok, WorkerPid} ->
+ handle_clidata(Arg, WorkerPid);
+ {error, Error} ->
+ Error
+ end
end.
+%% Sanitize CGI executable
+exe_ok(Exe) ->
+ NotAllowed = [$$,$`,$(,$),$;,$|,$<,$>,$&],
+ not lists:any(fun(C) -> lists:member(C, NotAllowed) end, Exe).
cgi_start_worker(Arg, Exefilename, Scriptfilename, Pathinfo, ExtraEnv, SC) ->
ExeFN = case Exefilename of
@@ -532,16 +540,19 @@ cgi_start_worker(Arg, Exefilename, Scriptfilename, Pathinfo, ExtraEnv, SC) ->
"" -> exeof(Scriptfilename);
FN -> FN
end,
- PI = case Pathinfo of
- undefined -> Arg#arg.pathinfo;
- OK -> OK
- end,
- WorkerPid = proc_lib:spawn(?MODULE, cgi_worker,
- [self(), Arg, ExeFN, Scriptfilename,
- PI, ExtraEnv, SC]),
- WorkerPid.
-
-
+ case exe_ok(ExeFN) of
+ true ->
+ PI = case Pathinfo of
+ undefined -> Arg#arg.pathinfo;
+ OK -> OK
+ end,
+ WorkerPid = proc_lib:spawn(?MODULE, cgi_worker,
+ [self(), Arg, ExeFN, Scriptfilename,
+ PI, ExtraEnv, SC]),
+ {ok, WorkerPid};
+ false ->
+ {error, {status, 403}}
+ end.
cgi_worker(Parent, Arg, Exefilename, Scriptfilename, Pathinfo, ExtraEnv0, SC) ->
ExtraEnv = lists:map(fun({K,V}) when is_binary(K), is_binary(V) ->
--
2.28.0
|