0%

记一个 $ _REQUEST 参数名问题

遇到这一类题目:

1
$username = isset($_POST['a_b.c']) ? $_POST['a_b.c'] : die("please input something");

首先我们知道正常post传入一个 a_b.c 的话它实际会被解析为 a_b_c 也就是无法正常传入 $_['a_b.c']

解决办法

我们只需要将第一个_ 改为 [ 就可以了。也就是post一个 a[b.c = 123 就可绕过了。

解析

我们看看底层的处理方式:(main/php_variables.c)

这里我是直接拿的别人的图,我太菜了找不到这文件。
从图片中我们可以看到当出现 [ 时我们的参数名指针值会变为 0 ,并且 break 。就是说我们[后面如果出现 空格 或者点 也不会被替换为 下划线了。但是这里的 [ 也不是我们想要的样子呀?
我们看看 https://bugs.php.net/bug.php?id=78236 这个链接。这里指出 [ 会被替换为 _ 同时我们可以顺带了解到 只会替换第一个[

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
“ [”只会被替换一次吗?

测试脚本:
---------------
<form method =“ post”>
<input type =“ text” name =“ id [name” value =“ 1”>
<input type =“ text” name =“ id [[name” value =“ a”>
<input type =“ submit”>
</ form>

预期结果:
----------------
数组(
'id_name'=>'1',
'id__name'=>'a',


实际结果:
--------------
数组(
'id_name'=>'1',
'id_ [name'=>'a',

那么这样我们就达到了绕过效果。

补充知识点

参照: https://www.php.net/manual/en/language.variables.external.php
这里指出 如果外部变量名称以有效的数组语法开头,则尾部字符将被静默忽略。例如, 变为$_REQUEST[‘foo’][‘bar’]。
测试代码:

1
2
<?php
echo $_GET['foo']['bar'];

我们输入:

1
?foo[bar]az=123213123123

可以看到回显:

这正验证了上面的说法。


-------------本文结束感谢您的阅读-------------