我有一个需要的项目,使用用户输入将文件包含到PHP脚本中。用户输入可以是任何相对URL(EX:/folder1/folder2/file.jpg,/ folder1 / folder2 /)
以下是一个万无一失的正则表达式来检查输入是否合理:
if(preg_match('/^(\/[-_a-zA-Z0-9]+)+\/?$/D', $_GET['loc']))
{
//Location is good!
}
显然我希望避免任何本地文件包含攻击。在我获得白名单建议而不是包含上述文件之前,我有1000个文件,所以一个switch语句或if / else不会工作。
答案 0 :(得分:2)
您可以将所有文件都包含在一个目录中/x/y/data
然后按以下方式进行检查:
$filename = realpath("/x/y/data/$_POST[location]");
// Make sure that $filename is under /usr/local/data
if ('/x/y/data/' = = substr($filename, 0, 10)) {
// safe..include the file.
} else {
// not safe..reject.
}
答案 1 :(得分:1)
我会为所有允许的文件构建一个白名单,并且只允许与之匹配的文件。如果由于某种原因这是不实际的,那么我不情愿地尝试某种正则表达式(但路径分隔符取决于平台,所以祝你好运)。一定要用php指令open_basedir来锁定这个东西。如果发生某种情况,这至少可以减少损害。