Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是ASCII/&引用;PHP中唯一表示目录遍历的字节序列?_Php_Character Encoding_Filesystems_Validation - Fatal编程技术网

是ASCII/&引用;PHP中唯一表示目录遍历的字节序列?

是ASCII/&引用;PHP中唯一表示目录遍历的字节序列?,php,character-encoding,filesystems,validation,Php,Character Encoding,Filesystems,Validation,我有一个PHP应用程序,它使用一个$\u GET参数来选择文件系统上的JS/CSS文件 如果我拒绝输入字符串包含/、\或可见7位ASCII范围之外的字节的所有请求,那么当路径传递到PHP的底层(基于C的)文件函数时,这是否足以防止父目录遍历 我知道,但是有没有其他替代的/格式错误的字符编码技巧可能会被这些检查刺痛 以下是基本思想(不是生产代码): 更新:我的问题实际上是关于C文件系统函数如何解释任意ASCII序列(例如,如果存在未记录的转义序列),但我意识到这可能与系统有关,并且在实践中可能无法

我有一个PHP应用程序,它使用一个
$\u GET
参数来选择文件系统上的JS/CSS文件

如果我拒绝输入字符串包含
/
\
或可见7位ASCII范围之外的字节的所有请求,那么当路径传递到PHP的底层(基于C的)文件函数时,这是否足以防止父目录遍历

我知道,但是有没有其他替代的/格式错误的字符编码技巧可能会被这些检查刺痛

以下是基本思想(不是生产代码):

更新:我的问题实际上是关于C文件系统函数如何解释任意ASCII序列(例如,如果存在未记录的转义序列),但我意识到这可能与系统有关,并且在实践中可能无法回答


我的活动验证还需要
realpath($fullPath)
realpath($\u SERVER['DOCUMENT\u ROOT'])
开始,确保文件在DOC\u根目录中,但此帖子的目标是在允许异常的情况下,抛弃
realpath()
(在各种环境中都不可靠),但是有效的URI,如
/~user/[my files]/file.plugin.js

在过滤输入以确保安全性时,始终使用白名单,而不是黑名单

您应该拒绝所有与
/^([A-Za-z0-9\-]+\/?)*[A-Za-z0-9\-]+\.(js)\.(css)$/
不匹配的路径


这将只允许正常的分段路径,其中每个分段都有字母、数字或

可能需要一些重新构造,但即使您通过
。/../passwd
basename()
也会将其隔离。然后,您可以将所有要提供服务的文件放在一个文件夹中


给定
。/../../../../../a/b/c/d.txt
basename($f)
将是
d.txt
;对我来说,这种方法似乎更明智,而不是试图智胜用户而忘记漏洞。

你自己也提到过,但将输入的
realpath
与已知根进行比较是我能想到的最佳解决方案。Realpath将解决路径/文件系统的任何隐藏功能,包括符号链接。

这闻起来像是列举坏东西。你能通过创建一个合法角色的列表来采取更多的白名单方法吗;这是一个糟糕的想法,不管你用什么方式来分割它。当你这样做的时候,我建议你过滤输入。他想为子目录服务。@SLaks:因此:“可能需要一些重新编译”是的,我想我将不得不接受
realpath
的特性。
$f = $_GET['f']; // e.g. "path/to/file.js"

// goal: select only unhidden CSS/JS files within DOC_ROOT
if (! preg_match('@^[\x20-\x7E]+$@', $f)     // outside visible ASCII
   || false !== strpos($f, "./")             // has ./
   || false !== strpos($f, "\\")             // has \
   || 0 === strpos(basename($f), ".")        // .isHiddenFile
   || ! preg_match('@\\.(css|js)$i@', $f)    // not JS/CSS
   || ! is_file($_SERVER['DOCUMENT_ROOT'] . '/' . $f)) {
    die();
}
$content = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/' . $f);