From 59a5c5c2080bd0093715c07e7252850856fa4d52 Mon Sep 17 00:00:00 2001 From: "Tobias S. Josefowitz" <tobij@tobij.de> Date: Tue, 6 Oct 2020 23:51:31 +0200 Subject: [PATCH] Tools.Standalone.httpserver: Fix directory traversal vulnerability Thanks to Chris Angelico <rosuav@gmail.com> for the report. --- .../Tools.pmod/Standalone.pmod/httpserver.pike | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/modules/Tools.pmod/Standalone.pmod/httpserver.pike b/lib/modules/Tools.pmod/Standalone.pmod/httpserver.pike index b37a9d74ec..3ea90e7965 100644 --- a/lib/modules/Tools.pmod/Standalone.pmod/httpserver.pike +++ b/lib/modules/Tools.pmod/Standalone.pmod/httpserver.pike @@ -15,6 +15,8 @@ constant version = sprintf(#"Pike httpserver %d.%d.%d constant description = "Minimal HTTP-server."; +string cwd; + int main(int argc, array(string) argv) { int my_port = 8080; @@ -28,13 +30,14 @@ int main(int argc, array(string) argv) default: my_port=(int)argv[-1]; } + cwd = getcwd(); Protocols.HTTP.Server.Port(handle_request, my_port); write("%s is now accessible on port %d through http, " "without password.\n", getcwd(), my_port); return -1; } -string dirlist( string dir ) +string dirlist( string dir, string rel_dir ) { string res = "<html><head>\n" @@ -43,7 +46,7 @@ string dirlist( string dir ) ".even { background-color:#fefefe; }\n" "</style>\n" "</head><body>\n" - "<h1>"+Parser.encode_html_entities(dir[2..])+"</h1>" + "<h1>"+Parser.encode_html_entities(rel_dir)+"</h1>" "<table cellspacing='0' cellpadding='2'>\n" "<tr><th align='left'>Filename</th>" "<th align='right'>Type</th>" @@ -81,8 +84,9 @@ string file_not_found(string fname) void handle_request(Protocols.HTTP.Server.Request request) { - string file = "."+combine_path("/",request->not_query); - file = Protocols.HTTP.uri_decode(file); + string file = Protocols.HTTP.uri_decode(request->not_query); + string rel_file = combine_path_unix("/", file)[1..]; + file = combine_path(cwd, rel_file); Stdio.Stat s = file_stat( file ); if( !s ) request->response_and_finish( (["data": @@ -90,7 +94,7 @@ void handle_request(Protocols.HTTP.Server.Request request) "type":"text/html", "error":404]) ); else if( s->isdir ) - request->response_and_finish( ([ "data":dirlist(file), + request->response_and_finish( ([ "data":dirlist(file, rel_file), "type":"text/html" ]) ); else request->response_and_finish( ([ "file":Stdio.File(file), -- GitLab