介绍下 PHP 的变量覆盖

有几个 PHP 函数在不安全地使用时,极易引发变量覆盖漏洞

1. extract()

extract()函数从一个数组中导入变量到当前的符号表。它会根据数组的键名创建同名的变量,并将键值赋给这些新变量

  • 漏洞示例:

    <?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() 时,务必指定第二个参数 $flagsEXTR_SKIPEXTR_PREFIX_ALL,以防止覆盖现有变量。例如:extract($_GET, EXTR_SKIP);

2. parse_str()

parse_str()函数用于解析URL参数字符串,并将其作为变量导入到当前作用域

  • 漏洞示例:

    <?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
    $name = 'default';
    
    foreach ($_GET as $key => $value) {
        // 动态地创建变量名
        $$key = $value;
    }
    
    echo "Hello, " . $name;
    ?>
    

    如果URL为 ?name=hacker$key 的值为 name$value 的值为 hacker。那么 $$key 实际上就是 $name,它的值被设置为 hacker。攻击者可以通过这种方式覆盖 $name 变量

  • 安全建议: 避免在没有严格过滤的情况下使用双重美元符来动态创建变量

Copyright © 版权信息 all right reserved,powered by Gitbook该文件修订时间: 2025-09-25 03:13:02

results matching ""

    No results matching ""