php:查询字符串中的路径 - 防止黑客攻击和错误的最佳方法?

时间:2010-10-20 21:02:45

标签: php directory

嘿伙计们, 我知道这不是最好的方法,但整个事情只是一个不需要更困难的小项目。

我正在传递目录名以及我的网址,例如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"); } 
你会做什么?

1 个答案:

答案 0 :(得分:2)

您应该将用户输入映射到预定的有效文件名列表,而不是允许使用任意路径。

话虽如此,如果您只是在个人开发机器上进行实验,您可以在任何用户提交的路径前添加一个允许的基本目录的路径,以帮助防止系统遍历。此外,禁止包含./../~/的任何提交路径(不仅仅是在字符串的开头,而是在任何地方)。

您可以使用preg_match

if (preg_match('#(\./|\.\./|~/|\\\)#', $_GET['p'])) {
    // disallow
}

同样,这仅用于实验性开发目的。对于任何实际使用的代码,您应该将输入映射到预定的有效路径列表。

此外,您的代码逻辑存在缺陷。 PATH永远不会在第一次使用之前设置,即使你设置它realpath也会使用它来转义使substr检查无效的多个字符,并且你正在使用一个定义变量更合适。