来源:自学PHP网 时间:2015-04-17 11:59 作者: 阅读:次
[导读] 使用PHP 构建的Web 应用如何避免XSS 攻击Web 2.0 的发展为网络用户的互动提供了更多机会。用户通过在论坛发表评论,或是在博客发表留言都可能有意或无意输入一些破坏性的内容,从而造...
使用PHP 构建的Web 应用如何避免XSS 攻击
Web 2.0 的发展为网络用户的互动提供了更多机会。用户通过在论坛发表评论,或是在博客发表留言都可能有意或无意输入一些破坏性的内容,从而造成网页不能正常显示,影响其它用户的使用。XSS 全称为Cross Site Scripting,因为CSS 已经用作样式表的简称,故称为XSS。XSS 是一种常见的网站攻击的方法。其原理是通过在网页的输入框输入一些恶意的内容,通常是JavaScript 脚本片段,而这些恶意输入在提交之后并重新读回到客户端时,浏览器会解释执行这些恶意的脚本内容,从而影响网页的正常显示。 本文首先简单介绍开发测试人员如何对Web 应用进行XSS 漏洞测试,如何借助工具绕过客户端JavaScript 校验输入恶意数据;然后针对使用PHP 语言构建的Web 站点,从在输出端对动态内容进行编码、以及在服务器端对输入进行检测两方面介绍如何避免恶意的XSS 攻击。 对Web 应用进行XSS 漏洞测试 测试路径 对WEB 应用进行XSS 漏洞测试,不能仅仅局限于在WEB 页面输入XSS 攻击字段,然后提交。绕过JavaScript 的检测,输入XSS 脚本,通常被测试人员忽略。下图为XSS 恶意输入绕过JavaScript 检测的攻击路径。 图1. XSS 攻击测试路径– 绕过JavaScript 校验 常见的XSS 输入
测试工具 很多工具可以在浏览器发送Get/Post 请求前将其截取,攻击者可以修改请求中的数据,从而绕过JavaScript 的检验将恶意数据注入服务器。以下是一些常用的截取HTTP 请求的工具列表。
如图2所示: TamperIE 绕过客户端浏览器JavaScript 的校验,在POST 请求提交时将其截取,用户可以任意修改表单输入项name 和message 的值,譬如将message 的值修改为 "<script>alert(“XSS hole!!”);</script>",然后点击”Send altered data” 按钮,将修改后的恶意数据发送给Web 服务器。 图2. 使用TamperIE 截取Post 请求 在输出端对动态内容进行编码 对一个Web 应用而言,其动态内容可能来源于用户输入、后台数据库、硬件状态改变或是网络信息等。动态内容特别是来自用户输入的动态内容很有可能包含恶意数据,从而影响网页的正常显示或是执行恶意脚本。将动态内容安全地显示在浏览器端与动态内容所处的上下文背景有关,譬如动态内容处在HTML 正文、表单元素的属性、或是JavaScript 代码段中。对于一个基于PHP 语言的Web 应用,当执行 "echo"、"print"、"printf"、"<?=" 等语句时表示正在处理动态内容。本节将首先介绍PHP 提供的库函数htmlspecialchars() 的用法,此函数能将5 个HTML 特殊字符转化为可在网页显示的HTML 实体编码;然后将介绍一些常见背景下的XSS 攻击输入,以及如何在输出端对动态内容进行转义、编码从而避免XSS 攻击。 使用PHP 的htmlspecialchars() 显示HTML 特殊字符 从上文列举的XSS 恶意输入可以看到,这些输入中包含了一些特殊的HTML 字符如"<"、">"。当传送到客户端浏览器显示时,浏览器会解释执行这些HTML 或JavaScript 代码而不是直接显示这些字符串。< > & “ 等字符在HTML语言中有特殊含义,对于用户输入的特殊字符,如何直接显示在网页中而不是被浏览器当作特殊字符进行解析? HTML字符实体由& 符号、实体名字或者# 加上实体编号、分号三部分组成。以下为HTML 中一些特殊字符的编码。有的字符实体只有实体编号,没有对应的实体名字,譬如单引号。 表1. 一些HTML 特殊字符的实体编码
PHP 提供了 htmlspecialchars() 函数可以将HTML 特殊字符转化成在网页上显示的字符实体编码。这样即使用户输入了各种HTML 标记,在读回到浏览器时,会直接显示这些HTML 标记,而不是解释执行。htmlspecialchars() 函数可以将以下五种HTML 特殊字符转成字符实体编码:
当设置ENT_QUOTES 标记时, 即调用 htmlspecialchars($str, ENT_QUOTES) 时,单引号也被转义。 当设置ENT_NOQUOTES 标记时,单引号和双引号都不会被转义。即调用 htmlspecialchars($str, ENT_NOQUOTES) 时,只有& < > 被转义。 不同背景下的动态内容的XSS 攻击及解决方案 XSS 攻击输入与动态内容所处的代码背景相关,譬如动态内容为表单元素属性的值、位于HTML 正文、或是Javascript 代码段中等等。 HTML 标记的属性为动态内容 Web 应用中,"input"、"style"、"color" 等HTML 标记的属性都可能为动态内容,其中"input" 标记的"value" 属性通常为动态内容。 例子1
攻击 XSS 输入
将动态内容替换 将 $msg 替换为恶意XSS 输入:
例子2
攻击XSS 输入
将动态内容替换 将 $msg 替换为恶意XSS 输入:
分析 从例子1 可以看到其XSS攻击输入中包含了HTML 特殊字符< > " 从例子2 可以看到其XSS 攻击输入中没有包含上节中提到的五种HTML 字符,但是"value"属性值没有使用双引号包围。 解决方案 调用 htmlspecialchars($str, ENT_QUOTES) 将以下5 种HTML 特殊字符< > &‘ “ 转义;同时使属性值被双引号包围。譬如:
注意事项 将input 的value 进行转义,必须考虑显示和存储数据的一致性问题,即显示在浏览器端和存储在服务器端后台的数据可能因为转义而变得不一致。譬如存储在服务器端的后台原始数据包含了以上5 种特殊字符,但是没有转义,为了防止XSS 攻击,在浏览器端输出时对HTML 特殊字符进行了转义: 1. 当再度将表单提交时,存储的内容将会变成转义后的值。 2. 当使用JavaScript 操作表单元素,需要使用到表单元素的值时,必须考虑到值可能已经被转义。 HTML 文本为动态内容 例子
攻击XSS输入
将动态内容替换 将 $welcome_msg 替换为恶意XSS 输入:
分析 在HTML 正文背景下,< > 字符会引入HTML 标记,& 可能会认为字符实体编码的开始,所以需要将< > & 转义 解决方案 为简洁起见,直接使用 htmlspecialchars() 将5 种HTML 特殊字符转义,如:
URL 的值为动态内容 Script/Style/Img/ActiveX/Applet/Frameset… 等标记的src 或href 属性如果为动态内容,必须确保这些URL 没有指向恶意链接。 例子1
攻击XSS输入
将动态内容替换 将 $script_url 替换为恶意XSS 输入:
例子2
攻击XSS输入
将动态内容替换 将 $img_url 替换为恶意XSS输入:
分析 一般情况下尽量不要让URL 的值被用户控制。如果用户需要自己定义自己的风格及显示效果,也不能让用户直接控制整个URL 的内容,而是提供预定义好的风格供用户设置、装配,然后由后台程序根据用户的选择组合成安全的URL 输出。 字符集编码 浏览器需要知道字符集编码才能正确地显示网页。如果字符集编码没有显式在content-type 或meta 中定义,浏览器会有算法猜测网页的字符集编码。譬如<script>alert(document.cookie)</script> 的UTF-7 编码为:
如果 +ADw-script+AD4-alert(document.cookie)+ADw-/script+AD4- 作为动态内容位于网页的顶端并传送到浏览器端,IE 会认为此网页是UTF-7 编码,从而使网页不能正常显示。 解决方案 显式定义网页的字符集编码,譬如
动态内容为 JavaScript 事件处理函数的参数 JavaScript 事件处理函数如onClick/onLoad/onError/onMouseOver/ 的参数可能包含动态内容。 例子
攻击XSS输入
将动态内容替换 HTML 解析器会先于JavaScript 解析器解析网页,将 $target_url 替换为恶意XSS 输入:
动态内容位于JavaScript 代码段中 例子
攻击XSS输入1
将动态内容替换 将 $welcome_msg 替换为恶意XSS 输入:
攻击XSS输入2
将动态内容替换 将 $welcome_msg 替换为恶意XSS 输入:
分析 如上文所示,在JavaScript 背景中使用动态内容需要非常谨慎。一般情况下,尽量避免或减少在Javascript 的背景下使用动态内容,如果必须使用动态内容,在开发或代码审计时必须考虑这些动态内容可能的取值,是否会导致XSS 攻击。 建立PHP库函数校验输入 Web 开发人员必须了解,仅仅在客户端使用JavaScript 函数对非法输入进行检测过滤对于构建安全的WEB 应用是不够的。如上文所述,攻击者可以轻易地借助工具绕过JavaScript 校验甚至SSL 加密输入恶意数据。在输出端对动态内容进行编码也只能起到一种双重保护的作用,更重要的应该在服务器端对输入进行校验。PHP 提供了strpos()、strstr()、preg_match() 等函数可用于检测非法字符和字符串;preg_replace() 函数可用于替换非法字符串。OWASP PHP Filters 开源项目提供了一些PHP 库函数用于过滤非法输入可作为参考。一些常见的检测和过滤包括:
总结 Web 应用的安全性是一个很重要、覆盖范围很广泛的主题。为了防止常见的XSS 的攻击,Web 开发人员必须明白不能仅仅只在客户端使用JavaScript 对输入进行检测、过滤;同时还应建立服务器端的输入校验、输出编码库函数;在服务器端检测、过滤输入;根据动态内容所处的背景将特殊字符进行编码后再传送给浏览器端显示。 参考资料
周婷,软件工程师,目前在IBM 中国软件开发技术实验室从事刀片服务器管理固件的开发工作。您可以通过 zhouting@cn.ibm.com和她联系。 刘鑫,目前在IBM 中国系统技术实验室从事服务器管理固件的开发工作。 刘坚, 软件工程师, Linux爱好者, 目前在IBM 中国软件开发技术实验室从事刀片服务器管理固件的开发工作。您可以通过liujsh@cn.ibm.com 和他联系。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com