我正在传递目录名以及我的网址,例如domain.com?p=folder/subfolder/etc
我正在寻找检查目录是否存在的最佳方法,并且我希望(至少)能够防止人们在层次结构中上升。
现在我正在做的事情(几乎)有效,但我觉得有更好,更简单,更短的方式:
if(isset($_GET['p'])) {
if (realpath($_GET['p'])) {
if (substr(PATH, 0, 1) == "" || substr(PATH, 0, 1) == "/" || substr(PATH, 0, 2) == "./" || substr(PATH, 0, 3) == "../") {
print "directory is forbidden!";
} else {
define(PATH, $_GET['p']);
}
} else {
print "directory does not exist!";
}
} else { define(PATH, "root"); }
你会做什么?
答案 0 :(得分:2)
您应该将用户输入映射到预定的有效文件名列表,而不是允许使用任意路径。
话虽如此,如果您只是在个人开发机器上进行实验,您可以在任何用户提交的路径前添加一个允许的基本目录的路径,以帮助防止系统遍历。此外,禁止包含./
,../
或~/
的任何提交路径(不仅仅是在字符串的开头,而是在任何地方)。
您可以使用preg_match。
if (preg_match('#(\./|\.\./|~/|\\\)#', $_GET['p'])) {
// disallow
}
同样,这仅用于实验性开发目的。对于任何实际使用的代码,您应该将输入映射到预定的有效路径列表。
此外,您的代码逻辑存在缺陷。 PATH
永远不会在第一次使用之前设置,即使你设置它realpath
也会使用它来转义使substr
检查无效的多个字符,并且你正在使用一个定义变量更合适。