如果你还能记起早期Web应用开发中使用C开发CGI程序的话,一定会对繁琐的表单处理深有体会。当PHP的register_globals配置选项打开时,复杂的原始表单处理不复存在,公用变量会自动建立。它让PHP编程变得容易和方便,但同时也带来了安全隐患。

用户输入从何而来?第一个源是 GET、POST 和 COOKIE 数据。一般称为 GPC 数据。此数据的可识别程序依赖于一个有争议的 php.ini设置:register_globals。在 PHP V4.3.0 以后,register_globals 默认情况下被设置为 Off。但是几年前,在 PHP 中,register_globals 的默认值是打开的,所以存在很多需要它的代码。

事实上,register_globals是无辜的,它并不会产生漏洞,同时还要开发者犯错才行。可是,有两个主要原因导致了您必须在开发和布署应用时关闭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。

审计代码的教训:设法关闭 register_globals。如果不打开 register_globals 应用程序就不能运行,并且您无法修改它,或者在应用程序必须运行的地方您无法控制 PHP 配置,则需要在条件块中查找所有全局变量设置,或者通过某些函数调用进入全局范围。如果 register_globals 为打开状态,则这两种情形都是由用户将变量设置为任意值引起的。

找到这些变量的好办法是将 php.ini 设置 error_reporting 设置为 E_ALL,同时使用 log_errors 或 display_errors,这样,所有 PHP 警告和错误都会被分别记录在文件中或显示在屏幕上。每当使用未初始化的变量(假定具有值)时,您将得到一条 E_NOTICE。这像 C 和 Java? 语言中那样,仍然与让 PHP 要求声明 变量有所不同。结果,当我们的第一个版本的脚本运行时,出现的错误消息是:

1 Notice: Undefined variable: authorized in C:\var\www\articles\press.php
2 on line 15

只要用户没有权限,错误就发生在第 15 行,而不是起初设置变量的第 5 行。PHP 在布尔上下文中将不确定的变量解释为假(参阅 参考资料 中列出的 PHP 手册中的“类型强制转换”),这样代码无论如何都会“正常运行”了 —— 除非有人暗中使用别的方式定义 $authorized。

如果您必须要开发一个在register_globals开启的环境中布署的应用时,很重要的一点是您必须要初始化所有变量并且把error_reporting 设为 E_ALL(或 E_ALL | E_STRICT)以对未初始化变量进行警告。当register_globals开启时,任何使用未初始化变量的行为几乎就意味着安全漏洞。

转载于:https://www.cnblogs.com/cyjaysun/p/4199513.html

PHP安全编程:register_globals的安全性相关推荐

  1. 并发编程-06线程安全性之可见性 (synchronized + volatile)

    文章目录 线程安全性文章索引 脑图 可见性定义 导致不可见的原因 可见性 -synchronized (既保证原子性又保证可见性) 可见性 - volatile(但不保证操作的原子性) volatil ...

  2. 并发编程-05线程安全性之原子性【锁之synchronized】

    文章目录 线程安全性文章索引 脑图 概述 原子性synchronized 修饰的4种对象 修饰代码块 作用范围及作用对象 Demo 多线程下 同一对象的调用 多线程下不同对象的调用 修饰方法 作用范围 ...

  3. 并发编程-04线程安全性之原子性Atomic包的4种类型详解

    文章目录 线程安全性文章索引 脑图 概述 原子更新基本类型 Demo AtomicBoolean 场景举例 原子更新数组 Demo 原子更新引用类型 Demo 原子更新字段类型 使用注意事项: Dem ...

  4. 并发编程-03线程安全性之原子性(Atomic包)及原理分析

    文章目录 线程安全性文章索引 脑图 线程安全性的定义 线程安全性的体现 原子性 使用AtomicInteger改造线程不安全的变量 incrementAndGet源码分析-UnSafe类 compar ...

  5. Java多线程编程(3)--线程安全性

    一.线程安全性   一般而言,如果一个类在单线程环境下能够运作正常,并且在多线程环境下,在其使用方不必为其做任何改变的情况下也能运作正常,那么我们就称其是线程安全的.反之,如果一个类在单线程环境下运作 ...

  6. java 线程安全list_JAVA并发编程实战-线程安全性

    线程安全性: 对象的状态是指存储在状态变量(例如实例和静态域)中的数据. 对象的状态可能包括其他依赖对象的域. 例如:某个HashMap的状态不仅存储在HashMap对象本身,还存储在许多Map.En ...

  7. Java并发编程之线程安全性分析之原子性、可见性、有序性

    一:线程的安全性分析 如何理解线程安全: 当多个线程访问某个共享对象时,不管运行环境采用何种调度方式,或者这些线程如何交替执行,并且主调代码中不需要任何的额外同步操作或者协同操作,这个类都能表现出正确 ...

  8. shell编程中文件安全性的保证

    目的 监控Web站点目录(/var/html/www)下的所有文件是否被恶意篡改(文件内容被更改) 文件被更改会有如下特征: 大小可能会变化 修改时间会变化 文件内容会变化,利用md5sum指纹校验 ...

  9. 并发编程 (三) 线程安全性之避免线程不安全

    文章目录 一.如何保证线程安全 1.1.并发原子类 1.2.加锁机制 1.3.信号量同步共享数据 1.4.封闭线程,不共享数据 1.5.发布与逸出 二.设计线程安全的类 2.1.前提要素 2.2.无限 ...

最新文章

  1. 融合视频目标检测与单目标、多目标跟踪,港中文开源一体化视频感知平台 MMTracking...
  2. css阴影3d效果,3D立体带阴影的CSS圆角效果
  3. 手机linux系统指令大全,Linux系统指令大全
  4. 中台不是万能药,关于中台的思考和尝试
  5. Ant Design Blazor 发布 0.9.0,共100+人贡献!
  6. 如何判断程序猿在做什么
  7. lisp scheme 果壳_common lisp和scheme的区别
  8. 【NOIP2017Day1T3】【洛谷P3953】逛公园
  9. html标签的英文全拼,HTML标签全称对照
  10. ThinkPHP5零食商城系统(前后台)
  11. SpringBoot项目下载resources目录下模板文件
  12. Java跨年祝福语代码_2018跨年夜精选祝福语贺词
  13. 续编-联想原装系统OEM系统联想出厂系统联想原装系统Lenovo ThinkPad ThinkBook出厂预装系统原厂系统
  14. CSP-S初赛基础知识整理
  15. 大学计算机基础知识电子版,大学计算机基础考试知识点(完整版).pdf
  16. ShopXO开源电商系统源码支持PC+H5支付宝小程序微信小程序百度小程序头条amp;抖音小程序QQ小程序APP等
  17. python打包为可执行文件的扩展名,Python脚本文件(.py)打包为可执行文件(.exe)即避免命令行中包含Python解释器...
  18. 最小生成树--还是畅通工程
  19. linux cisco路由器,Linux认证:Linux用dynamic模拟cisco路由器
  20. Windows Server 2016 部署DNS

热门文章

  1. 一招教你在linux服务器配置Jenkins持续集成神器
  2. 经验分享|测试工程师转型测试开发历程
  3. 临时变量、引用参数和const
  4. maven打包忽略注解_Maven打包时遇到的一些坑和解决方案
  5. linux 自动挂载usb设备,Raspberry Pi 自动挂载USB存储设备
  6. Convolutional Neural Networks with Alternately Updated Clique
  7. 介绍一种在Xcode中删除一整行代码的快捷键设置,
  8. 【opencv】左右两张图片实现全景拼接
  9. OpenCv颜色直方图
  10. java套接字数据对不上,服务器不从多个客户端(Java套接字)接收数据