我做出的假设是,$_GET变量被解释为单引号字符串(而不是双引号字符串)。
我相信这是真的,因为根据以下测试结果(尝试自己进行目录遍历攻击):
$file = "../test.php";
/**
* same as file1 but using hexadecimal encoding, which is a feature
* only available to double quoted strings
* https://www.php.net/manual/en/language.types.string.php
*/
$file2 = "\x2e\x2e\x2ftest.php";
include $file1; // will succeed in my environment
include $file2; // will succeed in my environment
但是,如果我通过 $_GET 传递十六进制表示法,包括文件在内的内容都会失败:
$file3 = $_GET["path"]; // (string) \x2e\x2e\x2ftest.php
include $file3; // will fail in my environment
所以我的问题是:$_GET变量是否真的被解释为单引号字符串?(因为如果是这样,那么从用户输入中简单地删除两个连续的点可能会防止任何目录遍历攻击)
如果是这样,那么在php手册中是否有写明?
\x2e\x2e\x2ftest.php
,那么这就是你拥有的值。 - David$_GET
变量被解释为单引号字符串。你犯了一个混乱的错误。单引号和双引号是标记源代码片段为纯文本(即数据)而不是代码的一种方式。$_GET
是一个包含字符串的变量,即从URL中获取的纯文本,没有涉及到任何源代码。 - axiac