在 PHP 中清理文件路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1911382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sanitize file path in PHP
提问by SeanDowney
Greetings, I'm hoping to make my tiny program secure so that potential malicious users cannot view sensitive files on the server.
问候,我希望使我的小程序安全,以便潜在的恶意用户无法查看服务器上的敏感文件。
$path = "/home/gsmcms/public_html/central/app/webroot/{$_GET['file']}";
if(file_exists($path)) {
echo file_get_contents($path);
} else {
header('HTTP/1.1 404 Not Found');
}
Off the top of my head I know that input such as '../../../../../../etc/passwd' would be trouble, but wondering what other malcious inputs I should expect and how to prevent them.
在我的脑海中,我知道诸如“../../../../../../etc/passwd”之类的输入会很麻烦,但想知道我应该期待哪些其他恶意输入以及如何以防止它们。
回答by Bert Lamb
realpath()will let you convert any path that may contain relative information into an absolute path...you can then ensure that path is under a certain subdirectory that you want to allow downloads from.
realpath()可以让您将任何可能包含相对信息的路径转换为绝对路径……然后您可以确保该路径位于您想要允许下载的某个子目录下。
回答by philfreo
回答by Yauhen Yakimovich
Solution by the OP:
OP的解决方案:
$baseDir = "/home/gsmcms/public_html/central/app/webroot/";
$path = realpath($baseDir . $_GET['file']);
// if baseDir isn't at the front 0==strpos, most likely hacking attempt
if(strpos($path, $baseDir) !== 0 || strpos($path, $baseDir) === false) {
die('Invalid Path');
} elseif(file_exists($path)) {
echo file_get_contents($path);
} else {
header('HTTP/1.1 404 Not Found');
echo "The requested file could not be found";
}
回答by Matteo Riva
If you can, use a whitelistlike an array of allowed files and check the input against that: if the file asked by the user isn't present in that list, deny the request.
如果可以,请使用白名单(如允许的文件数组)并检查输入:如果用户请求的文件不在该列表中,则拒绝该请求。
回答by Cheekysoft
There is an additional and significant security risk here. This script will inject the source of a file into the output stream without any server-side processing. This means that all your source code of any accessible files will be leaked to the internet.
这里还有一个额外的重大安全风险。该脚本将文件源注入到输出流中,无需任何服务器端处理。这意味着任何可访问文件的所有源代码都将泄露到互联网。
回答by Toxiro
Even if you are using realpath, you should still strip all ".." before using it. Otherwise an attacker can read your servers entire directory structure with brute force, e.g. "valid_folder/../../test_if_this_folder_name_exists/valid_folder" - if the application accepts this path, the attacker knows that the folder exists.
即使您使用的是 realpath,您仍应在使用前去除所有“..”。否则攻击者可以暴力读取您服务器的整个目录结构,例如“valid_folder/../../test_if_this_folder_name_exists/valid_folder” - 如果应用程序接受此路径,则攻击者知道该文件夹存在。
回答by snoop_dog
To strip all /. /..or \. \.. and convert to all forward slash because the different environments will accept forward slash. This should provide a fairly safe filter for path input. In your code you should be comparing it to parent directories that you do not want access just in case.
去除全部/. /..或\。\.. 并转换为所有正斜杠,因为不同的环境会接受正斜杠。这应该为路径输入提供一个相当安全的过滤器。在您的代码中,您应该将它与您不想访问的父目录进行比较,以防万一。
$path = realpath(implode('/', array_map(function($value) {return trim($value, '.');}, explode('/', str_replace('\', '/', $path)))));

