跳转至

外部变量修改 (External Variable Modification)

外部变量修改漏洞发生在 Web 应用程序处理用户输入不当时,允许攻击者覆盖内部变量。在 PHP 中,如果 extract($_GET)extract($_POST)import_request_variables() 等函数在没有进行适当验证的情况下将用户控制的数据导入全局作用域,则可能会被滥用。这会导致安全问题,如非授权地更改应用程序逻辑、权限提升或绕过安全控制。

摘要 (Summary)

方法论 (Methodology)

PHP 中的 extract() 函数将变量从数组导入当前的符号表。虽然它看起来很方便,但它可能引入严重的安全风险,尤其是在处理用户提供的数据时。

  • 它允许覆盖现有变量。
  • 它可以导致变量污染,影响安全机制。
  • 它可以作为触发其他漏洞(如远程代码执行 (RCE) 和本地文件包含 (LFI))的组件 (gadget)

默认情况下,extract() 使用 EXTR_OVERWRITE,这意味着如果现有变量名与输入数组中的键名相同,它将替换现有变量

覆盖关键变量 (Overwriting Critical Variables)

如果在依赖特定变量的脚本中使用 extract(),攻击者可以对其进行操纵。

<?php
    $authenticated = false;
    extract($_GET);
    if ($authenticated) {
        echo "Access granted!";
    } else {
        echo "Access denied!";
    }
?>

利用方式:

在这个示例中,使用 extract($_GET) 允许攻击者将 $authenticated 变量设置为 true

http://example.com/vuln.php?authenticated=true
http://example.com/vuln.php?authenticated=1

污染文件包含 (Poisoning File Inclusion)

如果 extract() 与文件包含结合使用,攻击者可以控制文件路径。

<?php
    $page = "config.php";
    extract($_GET);
    include "$page";
?>

利用方式:

http://example.com/vuln.php?page=../../etc/passwd

全局变量注入 (Global Variable Injection)

⚠ 自 PHP 8.1.0 起,不再支持对整个 $GLOBALS 数组的写访问。

当应用程序对不受信任的值调用 extract 函数时覆盖 $GLOBALS

extract($_GET);

攻击者可以操纵全局变量

http://example.com/vuln.php?GLOBALS[admin]=1

修复建议 (Remediations)

使用 EXTR_SKIP 以防止覆盖:

extract($_GET, EXTR_SKIP);

参考资料 (References)