我继承了一个充满了需要register_globals
的代码的Web服务器。其中大部分是由多年来来去的随机人员编写的自定义代码。我已将其中的大部分内容修复为我所知道的脚本,但我的问题在于找到我不知道的内容。
我正在考虑编写一个应用程序来扫描Web服务器上的每个目录,以识别需要register_globals
的PHP脚本。这样做有一个很好的策略吗?
我考虑过的一种方法涉及以某种方式强制PHP报告所有错误,执行脚本以及检查未定义的变量通知。我可以构建一个为此读取STDERR
流的应用程序。
你能想到更好的方法吗?
答案 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()