查找需要register_globals的PHP脚本

时间:2011-02-03 18:37:14

标签: php register-globals

我继承了一个充满了需要register_globals的代码的Web服务器。其中大部分是由多年来来去的随机人员编写的自定义代码。我已将其中的大部分内容修复为我所知道的脚本,但我的问题在于找到我不知道的内容。

我正在考虑编写一个应用程序来扫描Web服务器上的每个目录,以识别需要register_globals的PHP脚本。这样做有一个很好的策略吗?

我考虑过的一种方法涉及以某种方式强制PHP报告所有错误,执行脚本以及检查未定义的变量通知。我可以构建一个为此读取STDERR流的应用程序。

你能想到更好的方法吗?

5 个答案:

答案 0 :(得分:7)

大多数IDE会向您显示未定义的变量,例如PHPStorm。您可以让它扫描所有源文件,您将收到有关所有代码中未定义变量的通知,whiteout实际执行它。

这可能是最简单,最无痛的变体。或者,您显然可以使用Tokenizer编写自己的脚本,并识别所有T_VARIABLE s,这些T_VARIABLE先前未使用'=' expr {{1}}构造进行初始化。但这会更容易出错。使用IDE可能会以更少的工作量为您提供更好的结果。

答案 1 :(得分:3)

假设单个文件始终使用register_globals打开或关闭,您可以创建提交给脚本的所有表单元素名称的列表,然后检查此脚本是否使用$fieldname而不包含{{1} (或$_REQUEST['fieldname']$_POST数组)。

如果您在进行这些检查时可以保证非常高的代码覆盖率,那么您的“检查通知”方法就可以了(确保您没有遗漏任何内容 - 然后必须手动检查未覆盖的部分)。

答案 2 :(得分:2)

在检查日志中是否有关于编写的脚本症状时,期望全局变量可能会有所帮助,阅读代码是实现此目的的唯一方法。如果你想自动执行此操作,则需要构建或依赖PHP解释器;否则你注定会错过嵌套在条件,潜在的逃避等内容的东西。

答案 3 :(得分:1)

有一种方法可以找到注册全局的用法,它们是运行代码中的字符串。您可以创建以下脚本并使用PHP auto_prepend_file ini选项将其添加到现有代码中。

<?php

class revealGlobalsUsage {

    public $globalName;
    public $globalVal;

    public function __construct($name, $val)
    {
        $this->globalName = $name;
        $this->globalVal = $val;
    }

    public function __toString()
    {
        $backtrace = debug_backtrace();

        // log backtrace here...

        return $this->globalVal;
    }
}

// overwrite globals that have been set from GET and POST requests
foreach ($_REQUEST as $name => $val) {
    // Strings that are cast to integers will fail as there 
    // is no __toString equivalent for integers/bool/float etc.
    if (is_string($val) && !is_numeric($val)) {
        $GLOBALS[$name] = new revealGlobalsUsage($name, $val);
    }

    // You can log all GET/POST requests here...
}

对于整数等,您需要修补PHP:https://gist.github.com/ircmaxell/1966809

答案 4 :(得分:1)

我在拥有数千个文件的庞大代码库中遇到了这个问题。受@sschueller发布的解决方案的启发,我测试了这个auto_prepend_file代码,该代码记录了调查事件。此方法还应与解析/标记一起使用以捕获所有实例。

.copy()