PHP安全编程:register_globals的安全性
如果你还能记起早期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的安全性相关推荐
- 并发编程-06线程安全性之可见性 (synchronized + volatile)
文章目录 线程安全性文章索引 脑图 可见性定义 导致不可见的原因 可见性 -synchronized (既保证原子性又保证可见性) 可见性 - volatile(但不保证操作的原子性) volatil ...
- 并发编程-05线程安全性之原子性【锁之synchronized】
文章目录 线程安全性文章索引 脑图 概述 原子性synchronized 修饰的4种对象 修饰代码块 作用范围及作用对象 Demo 多线程下 同一对象的调用 多线程下不同对象的调用 修饰方法 作用范围 ...
- 并发编程-04线程安全性之原子性Atomic包的4种类型详解
文章目录 线程安全性文章索引 脑图 概述 原子更新基本类型 Demo AtomicBoolean 场景举例 原子更新数组 Demo 原子更新引用类型 Demo 原子更新字段类型 使用注意事项: Dem ...
- 并发编程-03线程安全性之原子性(Atomic包)及原理分析
文章目录 线程安全性文章索引 脑图 线程安全性的定义 线程安全性的体现 原子性 使用AtomicInteger改造线程不安全的变量 incrementAndGet源码分析-UnSafe类 compar ...
- Java多线程编程(3)--线程安全性
一.线程安全性 一般而言,如果一个类在单线程环境下能够运作正常,并且在多线程环境下,在其使用方不必为其做任何改变的情况下也能运作正常,那么我们就称其是线程安全的.反之,如果一个类在单线程环境下运作 ...
- java 线程安全list_JAVA并发编程实战-线程安全性
线程安全性: 对象的状态是指存储在状态变量(例如实例和静态域)中的数据. 对象的状态可能包括其他依赖对象的域. 例如:某个HashMap的状态不仅存储在HashMap对象本身,还存储在许多Map.En ...
- Java并发编程之线程安全性分析之原子性、可见性、有序性
一:线程的安全性分析 如何理解线程安全: 当多个线程访问某个共享对象时,不管运行环境采用何种调度方式,或者这些线程如何交替执行,并且主调代码中不需要任何的额外同步操作或者协同操作,这个类都能表现出正确 ...
- shell编程中文件安全性的保证
目的 监控Web站点目录(/var/html/www)下的所有文件是否被恶意篡改(文件内容被更改) 文件被更改会有如下特征: 大小可能会变化 修改时间会变化 文件内容会变化,利用md5sum指纹校验 ...
- 并发编程 (三) 线程安全性之避免线程不安全
文章目录 一.如何保证线程安全 1.1.并发原子类 1.2.加锁机制 1.3.信号量同步共享数据 1.4.封闭线程,不共享数据 1.5.发布与逸出 二.设计线程安全的类 2.1.前提要素 2.2.无限 ...
最新文章
- 融合视频目标检测与单目标、多目标跟踪,港中文开源一体化视频感知平台 MMTracking...
- css阴影3d效果,3D立体带阴影的CSS圆角效果
- 手机linux系统指令大全,Linux系统指令大全
- 中台不是万能药,关于中台的思考和尝试
- Ant Design Blazor 发布 0.9.0,共100+人贡献!
- 如何判断程序猿在做什么
- lisp scheme 果壳_common lisp和scheme的区别
- 【NOIP2017Day1T3】【洛谷P3953】逛公园
- html标签的英文全拼,HTML标签全称对照
- ThinkPHP5零食商城系统(前后台)
- SpringBoot项目下载resources目录下模板文件
- Java跨年祝福语代码_2018跨年夜精选祝福语贺词
- 续编-联想原装系统OEM系统联想出厂系统联想原装系统Lenovo ThinkPad ThinkBook出厂预装系统原厂系统
- CSP-S初赛基础知识整理
- 大学计算机基础知识电子版,大学计算机基础考试知识点(完整版).pdf
- ShopXO开源电商系统源码支持PC+H5支付宝小程序微信小程序百度小程序头条amp;抖音小程序QQ小程序APP等
- python打包为可执行文件的扩展名,Python脚本文件(.py)打包为可执行文件(.exe)即避免命令行中包含Python解释器...
- 最小生成树--还是畅通工程
- linux cisco路由器,Linux认证:Linux用dynamic模拟cisco路由器
- Windows Server 2016 部署DNS
热门文章
- 一招教你在linux服务器配置Jenkins持续集成神器
- 经验分享|测试工程师转型测试开发历程
- 临时变量、引用参数和const
- maven打包忽略注解_Maven打包时遇到的一些坑和解决方案
- linux 自动挂载usb设备,Raspberry Pi 自动挂载USB存储设备
- Convolutional Neural Networks with Alternately Updated Clique
- 介绍一种在Xcode中删除一整行代码的快捷键设置,
- 【opencv】左右两张图片实现全景拼接
- OpenCv颜色直方图
- java套接字数据对不上,服务器不从多个客户端(Java套接字)接收数据