Package: yaws / 2.0.6+dfsg-1+deb10u1

Sanitize-CGI-requests.patch Patch series | download
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
--- a/src/yaws_cgi.erl
+++ b/src/yaws_cgi.erl
@@ -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