本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。
当 register_globals 打开以后,各种变量都被注入代码,例如来自 HTML 表单的请求变量。再加上 PHP 在使用变量之前是无需进行初始化的,这就使得更容易写出不安全的代码。这是个很艰难的抉择,但 PHP 社区还是决定默认关闭此选项。当打开时,人们使用变量时确实不知道变量是哪里来的,只能想当然。但是 register_globals 的关闭改变了这种代码内部变量和客户端发送的变量混杂在一起的糟糕情况。下面举一个错误使用 register_globals 的例子:
Example #1 错误使用 register_globals = on 的例子
<?php // 当用户合法的时候,赋值 $authorized = true if (authenticated_user()) { $authorized = true; } // 由于并没有事先把 $authorized 初始化为 false, // 当 register_globals 打开时,可能通过GET auth.php?authorized=1 来定义该变量值 // 所以任何人都可以绕过身份验证 if ($authorized) { include "/highly/sensitive/data.php"; } ?>
另一个例子是关于会话的。当 register_globals = on 的时候,$username 也可以用在下面的代码中,但要意识到 $username 也可能会从其它途径进来,比如说通过 URL 的 GET。
Example #2 使用会话时同时兼容 register_globals on 和 off 的例子
<?php // 我们不知道 $username 的来源,但很清楚 $_SESSION 是 // 来源于会话数据 if (isset($_SESSION['username'])) { echo "Hello <b>{$_SESSION['username']}</b>"; } else { echo "Hello <b>Guest</b><br />"; echo "Would you like to login?"; } ?>
Example #3 探测有害变量
<?php if (isset($_COOKIE['MAGIC_COOKIE'])) { // MAGIC_COOKIE 来自 cookie // 这样做是确保是来自 cookie 的数据 } elseif (isset($_GET['MAGIC_COOKIE']) || isset($_POST['MAGIC_COOKIE'])) { mail("admin@example.com", "Possible breakin attempt", $_SERVER['REMOTE_ADDR']); echo "Security violation, admin has been alerted."; exit; } else { // 这一次请求中并没有设置 MAGIC_COOKIE 变量 } ?>
当然,单纯地关闭 register_globals 并不代表所有的代码都安全了。对于每一段提交上来的数据,都要对其进行具体的检查。永远要验证用户数据和对变量进行初始化!把 error_reporting() 设为 E_NOTICE 级别可以检查未初始化的变量。