Files
Sec-Interview/_book/Chapter20/20-8.md
T
2025-11-08 21:00:06 +08:00

79 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### 介绍下 PHP 的变量覆盖
有几个 PHP 函数在不安全地使用时,极易引发变量覆盖漏洞
**1. `extract()`**
`extract()`函数从一个数组中导入变量到当前的符号表。它会**根据数组的键名创建同名的变量**,并将键值赋给这些新变量
- **漏洞示例:**
```php
<?php
$username = 'guest';
$password = '123456';
// 从 $_GET 中导入变量,但没有做任何过滤
extract($_GET);
if ($username === 'admin' && $password === 'mypassword') {
echo 'Login successful as admin!';
} else {
echo 'Login failed.';
}
?>
```
在这个例子中,攻击者可以通过URL `?username=admin&password=mypassword` 来覆盖 `$username` 和 `$password` 这两个变量,从而绕过身份验证
- **安全建议:** 使用 `extract()` 时,务必指定第二个参数 `$flags` 为 `EXTR_SKIP` 或 `EXTR_PREFIX_ALL`,以防止覆盖现有变量。例如:`extract($_GET, EXTR_SKIP);`
**2. `parse_str()`**
`parse_str()`函数用于解析URL参数字符串,并将其作为变量导入到当前作用域
- **漏洞示例:**
```php
<?php
$username = 'guest';
// 将请求的参数字符串解析为变量
parse_str($_SERVER['QUERY_STRING']);
if ($username === 'admin') {
echo 'Hello admin!';
}
?>
```
攻击者可以通过 `?username=admin` 来覆盖 `$username` 变量
- **安全建议:** 始终将 `parse_str()` 的第二个参数设置为一个数组变量,这样解析的结果会存入该数组,而不是直接创建全局变量。例如:`parse_str($_SERVER['QUERY_STRING'], $query_data);`
**3. `import_request_variables()`**
这个函数在PHP 5.4.0 版本后被移除。它的功能是把 `$_GET`、`$_POST` 或 `$_COOKIE` 中的变量导入到全局作用域。由于其固有的安全风险,**不应再使用**
**4. `$$` (双重美元符)**
双重美元符是一种特殊的变量语法,它会将一个变量的值作为另一个变量的名称
- **漏洞示例:**
```php
<?php
$name = 'default';
foreach ($_GET as $key => $value) {
// 动态地创建变量名
$$key = $value;
}
echo "Hello, " . $name;
?>
```
如果URL为 `?name=hacker``$key` 的值为 `name``$value` 的值为 `hacker`。那么 `$$key` 实际上就是 `$name`,它的值被设置为 `hacker`。攻击者可以通过这种方式覆盖 `$name` 变量
- **安全建议:** 避免在没有严格过滤的情况下使用双重美元符来动态创建变量