首页 > 解决方案 > php $_GET 它被解释为单引号还是双引号字符串?

问题描述

我假设 $_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手册的任何地方?

标签: phpdirectory-traversal

解决方案


简短答案: $_GET['path'] 是一个变量。只有在双引号中找到转义序列时,PHP 才会解释转义序列,而不是在变量中。->字符串手册

$get = "\x2e";
var_dump($get);  
//string(1) "."

$get = "\\"."x2e";
var_dump($get);
//string(4) "\x2e"

推荐阅读