Bug #71559 [Com]: Built-in HTTP server, we can downlaod file in web by bug

From: Date: Fri, 03 Jun 2016 17:46:02 +0000
Subject: Bug #71559 [Com]: Built-in HTTP server, we can downlaod file in web by bug
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201437@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71559&edit=1 ID: 71559 Comment by: cpascal dot gr at gmail dot com Reported by: setbanned at gmail dot com Summary: Built-in HTTP server, we can downlaod file in web by bug Status: Closed Type: Bug Package: Built-in web server Operating System: Windows only PHP Version: 7.0.3 Assigned To: ab Block user comment: N Private report: N New Comment: There is something more that i didn't catch in my router.php If server have a request like this: http://192.168.5.152/index.php./ or like this etc: http://192.168.5.152/index.php..../ We can't catch the bug and client can show our source code. So, we have to do some preg_replaces to catch all posible cases with one if. in my router.php we have to replace this line: if (substr($rcuri[0],-1) != ".") { with this lines: function str_ends_with($haystack, $needle) {return substr_compare($haystack, $needle, -strlen($needle)) === 0;} $rmdots = preg_replace('/\.{2,}/', '.',$rcuri[0]); $rmdots = preg_replace('/\/{2,}/', '/',$rmdots); $rmdots = preg_replace('/[\.\/]{2,}/', './',$rmdots); if (!str_ends_with($rcuri[0],'.') && !str_ends_with($rmdots,'.php./')) { Ok this is not the better way, we can make a very smart preg_match to do the same but, this code will do the job too. So, my router.php is now: <?php // router.php function str_ends_with($haystack, $needle) { return substr_compare($haystack, $needle, -strlen($needle)) === 0; } $rcuri = explode("?",$_SERVER["REQUEST_URI"]); $rmdots = preg_replace('/\.{2,}/', '.',$rcuri[0]); $rmdots = preg_replace('/\/{2,}/', '/',$rmdots); $rmdots = preg_replace('/[\.\/]{2,}/', './',$rmdots); if (!str_ends_with($rcuri[0],'.') && !str_ends_with($rmdots,'.php./')) { return false; } else { header("HTTP/1.0 404 Not Found"); echo '<!doctype html><html><head><title>404 Not Found</title><style> body { background-color: #fcfcfc; color: #333333; margin: 0; padding:0; } h1 { font-size: 1.5em; font-weight: normal; background-color: #9999cc; min-height:2em; line-height:2em; border-bottom: 1px inset black; margin: 0; } h1, p { padding-left: 10px; } code.url { background-color: #eeeeee; font-family:monospace; padding:0 2px;} </style> </head><body><h1>Not Found</h1><p>The requested resource <code class="url">'.$_SERVER["REQUEST_URI"].'</code> was not found on this server.</p></body></html>'; } ?> C. Paschalidis Software Developer / DBA Previous Comments: ------------------------------------------------------------------------ [2016-06-03 14:37:00] cpascal dot gr at gmail dot com Hi, There is an easy way to fix the "dot" security issue. You can just make a router.php to check the REQUEST_URI before the response: <?php // router.php $rcuri = explode("?",$_SERVER["REQUEST_URI"]); if (substr($rcuri[0],-1) != ".") { return false; } else { header("HTTP/1.0 404 Not Found"); ?> This will show you a blank 404 page if there is a dot in the end of URL (if there are any params i exclude them with explode...) If you want to "fake" the default 404 page, you can just echo it: <?php // router.php $rcuri = explode("?",$_SERVER["REQUEST_URI"]); if (substr($rcuri[0],-1) != ".") { return false; } else { header("HTTP/1.0 404 Not Found"); echo '<!doctype html><html><head><title>404 Not Found</title><style> body { background-color: #fcfcfc; color: #333333; margin: 0; padding:0; } h1 { font-size: 1.5em; font-weight: normal; background-color: #9999cc; min-height:2em; line-height:2em; border-bottom: 1px inset black; margin: 0; } h1, p { padding-left: 10px; } code.url { background-color: #eeeeee; font-family:monospace; padding:0 2px;} </style> </head><body><h1>Not Found</h1><p>The requested resource <code class="url">'.$_SERVER["REQUEST_URI"].'</code> was not found on this server.</p></body></html>'; } ?> You can put the router.php in the same dir with php.exe and run the server with: php.exe -S 127.0.0.1:80 router.php If you want to specify the document root, you must put -t param before -S param: php.exe -t "C:\vbserver\www_uncompress" -S 192.168.123.100:80 router.php C. Paschalidis Software Developer / DBA ------------------------------------------------------------------------ [2016-02-14 19:50:19] ab@php.net Automatic comment on behalf of ab Revision: http://git.php.net/?p=php-src.git;a=commit;h=ce4a2f0fc60309f429e4c04160a71befc283338a Log: Fixed bug #71559 Built-in HTTP server, we can downlaod file in web by bug ------------------------------------------------------------------------ [2016-02-10 22:21:51] ab@php.net Johannes, oh yeah, you've spotted it very well. The win32 namespace will cut off the trailing dots and spaces. I'll prepare a patch for next RCs. Thanks. ------------------------------------------------------------------------ [2016-02-10 17:01:19] johannes@php.net Anatol, you have an idea? - This seems to be Windows-specific. In php_cli_server_dispatch() we see that the extension is not "php" (which is correct, as the file extension is empty) so it dispatches a static file. In php_cli_server_begin_send_static() we do 1953 if (client->request.path_translated && strlen(client->request.path_translated) != client->request.path_translated_len) { 1954 /* can't handle paths that contain nul bytes */ 1955 return php_cli_server_send_error_page(server, client, 400); 1956 } 1957 1958 fd = client->request.path_translated ? open(client->request.path_translated, O_RDONLY): -1; Which succeeds and opens "foo.php" when "foo.php." is requested. ------------------------------------------------------------------------ [2016-02-09 20:05:15] stas@php.net Not a security issue since built-in server should not be used in production, but somebody may want to look at it and fix it still. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=71559 -- Edit this bug report at https://bugs.php.net/bug.php?id=71559&edit=1

« previous php.bugs (#201437) next »