php安全编程: register_globals的安全性
register_globals?本身并非安全风险。但是,它为跟踪用户输入和确保应用程序安全增加了难度。为什么会这样?
因为如果打开 register_globals,在全局名称空间和 $_GET、$_POST 或 $_COOKIE 数组中,将创建 GET、POST 和 COOKIE 传递到 PHP 脚本的所有变量。
下面是工作方式及其重要性的示例:
1 <?php 2 3 // See if the user has the secret cookie. 4 if (!empty($_COOKIE['secret'])) { 5 $authorized = true; 6 } 7 8 // Now let's go through a list of press releases and show them. 9 $releases = get_press_releases(); 10 foreach ($releases as $release) { 11 12 // Some releases are restricted. Only show them to people who can 13 // see secrets. 14 if ($release['secret']) { 15 if (!$authorized) { 16 continue; 17 } 18 } 19 20 // We must be allowed to see it. 21 showRelease($release); 22 } 23 ?>
您应该注意几件事。第一,依靠 cookie 来判断用户是否已通过身份验证不是个好主意 —— 因为人们可以很容易地设置自己的 cookie 值。
无论如何,此脚本的缺点在于,如果打开 register_globals,它就不具备安全性了。
下面介绍名为 press.php 的脚本。一般来说,当用户访问 press 发行版的脚本时,其浏览器将显示 http://www.example.com/company/press.php。
现在注意当用户擅自将其更改为 http://www.example.com/company/press.php?authorized=1 时将发生什么事?
看看前面的代码:仅当用户使用 cookie 时才设置 $authorized。它永远不会被设置为假。后来引入了 register_globals —— 它取代了刚才使用的 $_GET['authorized'],同时在全局范围内还存在一个值为 1 的变量 $authorized。因此,即使用户没有通过 cookie 检查,$authorized 后来在 foreach 循环中引用时,仍然会被验证为真。
修复此缺陷可以使用两种方式。其一,当然是关闭 register_globals。如果关闭它对您的生产站点没有影响,则这是个好主意。您需要测试一下应用程序,确保它没有因此中断运行。
另一种方式有点像“防御性编程”。我们只需要将 cookie 检查更改为以下形式即可:
1 <?php 2 3 // See if the user has the secret cookie. 4 $authorized = false; 5 if (!empty($_COOKIE['secret'])) { 6 $authorized = true; 7 } 8 ?>
这时,当用户将 ?authorized=1 添加到脚本 URL 时,$authorized 变量仍然被设置为 1 —— 但是它随即会被 $authorized = false 覆盖,只有那些实际具有秘密 cookie 的用户才能看到受限的 press 发行版。他们仍然可以设计自己的 cookie。
学习转自:http://www.nowamagic.net/librarys/veda/detail/1978