summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2019-10-18 16:40:44 +0100
committerMatt Caswell <matt@openssl.org>2019-10-28 13:20:02 +0000
commitb39c0475a671879e2dd6c7a29de1127139f2dc0d (patch)
tree39b852b1ca24f1e57789f0de0e1aaab385f7c0ff
parent0159a1bb41b385a00836e9e7baeadad2f014b788 (diff)
Fix an s_server arbitrary file read issue on Windows
Running s_server in WWW mode on Windows can allow a client to read files outside the s_server directory by including backslashes in the name, e.g. GET /..\myfile.txt HTTP/1.0 There exists a check for this for Unix paths but it is not sufficient for Windows. Since s_server is a test tool no CVE is assigned. Thanks to Jobert Abma for reporting this. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10215) (cherry picked from commit 0a4d6c67480a4d2fce514e08d3efe571f2ee99c9)
-rw-r--r--apps/s_server.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/apps/s_server.c b/apps/s_server.c
index ce7a1d64b6..97b65046bb 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -3045,6 +3045,12 @@ static int www_body(int s, int stype, unsigned char *context)
if (e[0] == ' ')
break;
+ if (e[0] == ':') {
+ /* Windows drive. We treat this the same way as ".." */
+ dot = -1;
+ break;
+ }
+
switch (dot) {
case 1:
dot = (e[0] == '.') ? 2 : 0;
@@ -3053,11 +3059,11 @@ static int www_body(int s, int stype, unsigned char *context)
dot = (e[0] == '.') ? 3 : 0;
break;
case 3:
- dot = (e[0] == '/') ? -1 : 0;
+ dot = (e[0] == '/' || e[0] == '\\') ? -1 : 0;
break;
}
if (dot == 0)
- dot = (e[0] == '/') ? 1 : 0;
+ dot = (e[0] == '/' || e[0] == '\\') ? 1 : 0;
}
dot = (dot == 3) || (dot == -1); /* filename contains ".."
* component */
@@ -3071,11 +3077,11 @@ static int www_body(int s, int stype, unsigned char *context)
if (dot) {
BIO_puts(io, text);
- BIO_printf(io, "'%s' contains '..' reference\r\n", p);
+ BIO_printf(io, "'%s' contains '..' or ':'\r\n", p);
break;
}
- if (*p == '/') {
+ if (*p == '/' || *p == '\\') {
BIO_puts(io, text);
BIO_printf(io, "'%s' is an invalid path\r\n", p);
break;