`
ssxxjjii
  • 浏览: 928600 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

解析如何防止XSS跨站脚本攻击

阅读更多

本文为大家提供了简单的实战模式以防止XSS跨站脚本攻击通过output escaping/encoding发动攻击。虽然存在大量跨站脚本攻击者,不过只要遵守本文提供的几个规则就能有效抵御XSS跨站脚本攻击。  这些规则适用于所有不同类别的XSS跨站脚本攻击,可以通过在服务端执行适当的解码来定位映射的XSS以及存储的XSS,由于XSS也存在很多特殊情况,因此强烈推荐使用解码库。另外,基于XSS的DOM也可以通过将这些规则运用在客户端的不可信数据上来定位。

    本文为大家提供了简单的实战模式以防止XSS跨站脚本攻击通过output escaping/encoding发动攻击。虽然存在大量跨站脚本攻击者,不过只要遵守本文提供的几个规则就能有效抵御XSS跨站脚本攻击。

  这些规则适用于所有不同类别的XSS跨站脚本攻击,可以通过在服务端执行适当的解码来定位映射的XSS以及存储的XSS,由于XSS也存在很多特殊情况,因此强烈推荐使用解码库。另外,基于XSS的DOM也可以通过将这些规则运用在客户端的不可信数据上来定位。

  不可信数据

  不可信数据通常是来自HTTP请求的数据,以URL参数、表单字段、标头或者Cookie的形式。不过从安全角度来看,来自数据库、网络服务器和其他来源的数据往往也是不可信的,也就是说,这些数据可能没有完全通过验证。

  应该始终对不可信数据保持警惕,将其视为包含攻击,这意味着在发送不可信数据之前,应该采取措施确定没有攻击再发送。由于应用程序之间的关联不断深化,下游直译程序执行的攻击可以迅速蔓延。

  传统上来看,输入验证是处理不可信数据的最好办法,然而,输入验证法并不是注入式攻击的最佳解决方案。首先,输入验证通常是在获取数据时开始执行的,而此时并不知道目的地所在。这也意味着我们并不知道在目标直译程序中哪些字符是重要的。其次,可能更加重要的是,应用程序必须允许潜在危害的字符进入,例如,是不是仅仅因为SQL认为Mr. O'Malley名字包含特殊字符他就不能在数据库中注册呢?

  虽然输入验证很重要,但这始终不是解决注入攻击的完整解决方案,最好将输入攻击作为纵深防御措施,而将escaping作为首要防线。

  解码(又称为Output Encoding)

  “Escaping”解码技术主要用于确保字符作为数据处理,而不是作为与直译程序的解析器相关的字符。有很多不同类型的解码,有时候也被成为输出“解码”。有些技术定义特殊的“escape”字符,而其他技术则包含涉及若干字符的更复杂的语法。

  不要将输出解码与Unicode字符编码的概念弄混淆了,后者涉及映射Unicode字符到位序列。这种级别的编码通常是自动解码,并不能缓解攻击。但是,如果没有正确理解服务器和浏览器间的目标字符集,有可能导致与非目标字符产生通信,从而招致跨站XSS脚本攻击。这也正是为所有通信指定Unicode字符编码(字符集)(如UTF-8等)的重要所在。

  Escaping是重要的工具,能够确保不可信数据不能被用来传递注入攻击。这样做并不会对解码数据造成影响,仍将正确呈现在浏览器中,解码只能阻止运行中发生的攻击。

  注入攻击理论

  注入攻击是这样一种攻击方式,它主要涉及破坏数据结构并通过使用特殊字符(直译程序正在使用的重要数据)转换为代码结构。XSS是一种注入攻击形式,浏览器作为直译程序,攻击被隐藏在HTML文件中。HTML一直都是代码和数据最差的mashup,因为HTML有很多可能的地方放置代码以及很多不同的有效编码。HTML是很复杂的,因为它不仅是层次结构的,而且还包含很多不同的解析器(XML、HTML、JavaScript、VBScript、CSS、URL等)。

  要想真正明白注入攻击与XSS的关系,必须认真考虑HTML DOM的层次结构中的注入攻击。在HTML文件的某个位置(即开发者允许不可信数据列入DOM的位置)插入数据,主要有两种注入代码的方式:

  Injecting UP,上行注入

  最常见的方式是关闭现有的context并开始一个新的代码context,例如,当你关闭HTML属性时使用">并开始新的<SCRIPT>标签。这种攻击将关闭原始context(层次结构的上层部分),然后开始新的标签允许脚本代码执行。记住,当你试图破坏现有context时你可以跳过很多层次结构的上层部分,例如</SCRIPT>可以终止脚本块,即使该脚本块被注入脚本内方法调用内的引用字符,这是因为HTML解析器在JavaScript解析器之前运行。

  Injecting DOWN,下行注入

  另一种不太常见的执行XSS注入的方式就是,在不关闭当前context的情况下,引入一个subcontext。例如,将<IMG src="...">改为<IMG src="javascript:alert(1)">,并不需要躲开HTML属性context,相反只需要引入允许在src属性内写脚本的context即可。另一个例子就是CSS属性中的expression()功能,虽然你可能无法躲开引用CSS属性来进行上行注入,你可以采用xss:expression(document.write(document.cookie))且无需离开现有context。

  同样也有可能直接在现有context内进行注入,例如,可以采用不可信的输入并把它直接放入JavaScript context。这种方式比你想象的更加常用,但是根本不可能利用escaping(或者任何其他方式)保障安全。从本质上讲,如果这样做,你的应用程序只会成为攻击者将恶意代码植入浏览器的渠道。

  本文介绍的规则旨在防止上行和下行XSS注入攻击。防止上行注入攻击,你必须避免那些允许你关闭现有context开始新context的字符;而防止攻击跳跃DOM层次级别,你必须避免所有可能关闭context的字符;下行注入攻击,你必须避免任何可以用来在现有context内引入新的sub-context的字符。

  积极XSS防御模式

  本文把HTML页面当作一个模板,模板上有很多插槽,开发者允许在这些插槽处放置不可信数据。在其他地方放置不可信数据是不允许的,这是“白名单”模式,否认所有不允许的事情。

  根据浏览器解析HTML的方式的不同,每种不同类型的插槽都有不同的安全规则。当你在这些插槽处放置不可信数据时,必须采取某些措施以确保数据不会“逃离”相应插槽并闯入允许代码执行的context。从某种意义上说,这种方法将HTML文档当作参数化的数据库查询,数据被保存在具体文职并与escaping代码context相分离。

  本文列出了最常见的插槽位置和安全放置数据的规则,基于各种不同的要求、已知的XSS载体和对流行浏览器的大量手动测试,我们保证本文提出的规则都是安全的。

  定义好插槽位置,开发者们在放置任何数据前,都应该仔细分析以确保安全性。浏览器解析是非常棘手的,因为很多看起来无关紧要的字符可能起着重要作用。

  为什么不能对所有不可信数据进行HTML实体编码?

  可以对放入HTML文档正文的不可行数据进行HTML实体编码,如<div>标签内。也可以对进入属性的不可行数据进行实体编码,尤其是当属性中使用引用符号时。但是HTML实体编码并不总是有效,例如将不可信数据放入<script>标签、事件处理器(如onmouseover) 、CSS内部或URL内等。即使你在每个位置都使用HTML实体编码的方法,仍然不能抵御跨站脚本攻击。对于放入不可信数据的HTML文档部分,必须使用escape语法,这也是下面即将讨论的问题。

  你需要一个安全编码库

  编写编码器并不是非常难,不过也有不少隐藏的陷阱。例如,你可能会使用一下解码捷径(JavaScsript 中的\"),但是,这些很容易被浏览器中的嵌套解析器误解,应该使用一个安全的专门解码库以确保这些规则能够正确执行。

  XSS防御规则

  下列规则旨在防止所有发生在应用程序的XSS攻击,虽然这些规则不允许任意向HTML文档放入不可信数据,不过基本上也涵盖了绝大多数常见的情况。你不需要采用所有规则,很多企业可能会发现第一条和第二条就已经足以满足需求了。请根据自己的需求选择规则。

  No.1 – 不要在允许位置插入不可信数据

  第一条规则就是拒绝所有数据,不要将不可信数据放入HTML文档,除非是下列定义的插槽。这样做的理由是在理列有解码规则的HTML中有很多奇怪的context,让事情变得很复杂,因此没有理由将不可信数据放在这些context中。

<script>...NEVER PUT UNTRUSTED DATA HERE...</script>   directly in a script
<!--...NEVER PUT UNTRUSTED DATA HERE...-->             inside an HTML comment
<div ...NEVER PUT UNTRUSTED DATA HERE...=test />       in an attribute name
<...NEVER PUT UNTRUSTED DATA HERE... href="/test" />   in a tag name

     更重要的是,不要接受来自不可信任来源的JavaScript代码然后运行,例如,名为“callback”的参数就包含JavaScript代码段,没有解码能够解决。

  No.2 – 在向HTML元素内容插入不可信数据前对HTML解码

  这条规则适用于当你想把不可信数据直接插入HTML正文某处时,这包括内部正常标签(div、p、b、td等)。大多数网站框架都有HTML解码的方法且能够躲开下列字符。但是,这对于其他HTML context是远远不够的,你需要部署其他规则。

   <body>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE... </body>  
<div>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</div>
以及其他的HTML常用元素


  使用HTML实体解码躲开下列字符以避免切换到任何执行内容,如脚本、样式或者事件处理程序。在这种规格中推荐使用十六进制实体,除了XML中5个重要字符(&、<、 >、 "、 ')外,还加入了斜线符,以帮助结束HTML实体。

      & --> &
  < --> <
  > --> >
  " --> "
  ' --> ' &apos; is not recommended
  / --> / forward slash is included as it helps end an HTML entity


      ESAPI参考实施

String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );


  No.3 – 在向HTML常见属性插入不可信数据前进行属性解码

  这条规则是将不可信数据转化为典型属性值(如宽度、名称、值等),这不能用于复杂属性(如href、src、style或者其他事件处理程序)。这是及其重要的规则,事件处理器属性(为HTML JavaScript Data Values)必须遵守该规则。

<div attr=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...>content</div>     inside UNquoted attribute
<div attr='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'>content</div>   inside single quoted attribute
<div attr="...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">content</div>   inside double quoted attribute

      除了字母数字字符外,使用小于256的ASCII值&#xHH格式(或者命名的实体)对所有数据进行解码以防止切换属性。这条规则应用广泛的原因是因为开发者常常让属性保持未引用,正确引用的属性只能使用相应的引用进行解码。未引用属性可以被很多字符破坏,包括[space] % * + , - / ; < = > ^ 和 |。

      ESAPI参考实施

String safe = ESAPI.encoder().encodeForHTMLAttribute( request.getParameter( "input" ) );

      No.4 – 在向HTML JavaScript Data Values插入不可信数据前,进行JavaScript解码

  这条规则涉及在不同HTML元素上制定的JavaScript事件处理器。向这些事件处理器放置不可信数据的唯一安全位置就是“data value”。在这些小代码块放置不可信数据是相当危险的,因为很容易切换到执行环境,因此请小心使用。

<script>alert('...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...')</script>     inside a quoted string
<script>x=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</script>            one side of an expression
<div onmouseover=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</div>        inside UNquoted event handler
<div onmouseover='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'</div>      inside quoted event handler
<div onmouseover="...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE..."</div>      inside quoted event handler

      除了字母数字字符外,使用小于256的ASCII值\xHH格式 对所有数据进行解码以防止将数据值切换至脚本内容或者另一属性。不要使用任何解码捷径(如\" )因为引用字符可能被先运行的HTML属性解析器相匹配。如果事件处理器被引用,则需要相应的引用来解码。这条规则的广泛应用是因为开发者经常让事件处理器保持未引用。正确引用属性只能使用相应的引用来解码,未引用属性可以使用任何字符(包括[space] % * + , - / ; < = > ^ 和|)解码。同时,由于HTML解析器比JavaScript解析器先运行,关闭标签能够关闭脚本块,即使脚本块位于引用字符串中。

       ESAPI参考实施

String safe = ESAPI.encoder().encodeForJavaScript( request.getParameter( "input" ) );


  No.5 – 在向HTML 样式属性值插入不可信数居前,进行CSS解码

  当你想将不可信数据放入样式表或者样式标签时,可以用此规则。CSS是很强大的,可以用于许多攻击。因此,只能在属性值中使用不可信数据而不能在其他样式数据中使用。不能将不可信数据放入复杂的属性(如url,、behavior、和custom (-moz-binding))。同样,不能将不可信数据放入允许JavaScript的IE的expression属性值。

<style>selector { property : ...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...; } </style>     property value
<span style=property : ...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...;>text</style>         property value



  除了字母数字字符外,使用小于256的ASCII值\HH格式对所有数据进行解码。不要使用任何解码捷径(如\" )因为引用字符可能被先运行的HTML属性解析器相匹配,防止将数据值切换至脚本内容或者另一属性。同时防止切换至expression或者其他允许脚本的属性值。如果属性被引用,将需要相应的引用进行解码,所有的属性都应该被引用。未引用属性可以使用任何字符(包括[space] % * + , - / ; < = > ^ 和|)解码。同时,由于HTML解析器比JavaScript解析器先运行,</script>标签能够关闭脚本块,即使脚本块位于引用字符串中。

      ESAPI参考实施

String safe = ESAPI.encoder().encodeForCSS( request.getParameter( "input" ) );

      No.6- 在向HTML URL属性插入不可信数据前,进行URL解码

  当你想将不可信数据放入链接到其他位置的link中时需要运用此规则。这包括href和src属性。还有很多其他位置属性,不过我们建议不要在这些属性中使用不可信数据。需要注意的是在javascript中使用不可信数据的问题,不过可以使用上述的HTML JavaScript Data Value规则。

<a href=http://...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...>link</a >        a normal link
<img src='http://...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...' />            an image source
<script src="http://...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE..." />         a script source


  除了字母数字字符外,使用小于256的ASCII值%HH 解码格式对所有数据进行解码。在数据中保护不可信数据:URL不能够被允许,因为没有好方法来通过解码来切换URL以避免攻击。所有的属性都应该被引用。未引用属性可以使用任何字符(包括[space] % * + , - / ; < = > ^ 和|)解码。 请注意实体编码在这方面是没用的。

      ESAPI参考实施

String safe = ESAPI.encoder().encodeForURL( request.getParameter( "input" ) );

转自:http://hi.baidu.com/xss0day/blog/item/213d2fa6a1912892d14358a0.html

分享到:
评论

相关推荐

    解决XSS跨站脚本攻击

    这篇文档是针对XSS漏洞的防范的简单解析。

    跨站脚本攻击实例解析

    Web安全深度剖析 跨站脚本攻击实例解析 跨站脚本攻击实例解析

    XSS利用文档

    反射性跨站脚本攻击的利用解析, XSS的高级利用部分总结,XSS跨站脚本攻击汇总。

    anti-xss:AntiAntiXSS | 通过PHP防止跨站点脚本(XSS)

    :Japanese_secret_button: 反XSS “跨站点脚本(XSS)是一种通常... 阅读此文本-&gt; XSS(跨站点脚本)预防备忘单测试此工具-&gt; Zed攻击代理(ZAP) 通过“ composer require”安装composer require voku/anti-xss 用法:

    Python-XSStrike是一个最先进的跨站脚本XSS检测套件

    XSStrike是一个Cross Site Scripting检测套件,配备四个手写解析器,一个智能有效负载生成器,一个强大的模糊引擎和一个非常快速的爬虫。

    Web安全之XSS攻击与防御小结

    跨站脚本攻击(CrossSiteScripting),缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。攻击者对含有漏洞的服务器发起...

    Web应用安全:存储型XSS.pptx

    4.例如,有一个发表动态的网站,攻击者可以在发表动态的表单中提交恶意代码,其他用户去查看攻击者的这条动态消息的时候,这些恶意脚本从服务端加载下来,被浏览器所解析和执行。 存储型XSS简介 2.存储型XSS与反射型...

    基于EBNF和二次爬取策略的XSS漏洞检测技术

    跨站脚本(XSS)攻击是目前互联网安全的最大威胁之一。针对传统基于渗透测试技术的漏洞检测方法中攻击向量复杂度低易被过滤、整体检测流程繁琐等问题,提出了一种基于扩展的巴科斯范式(EBNF)的攻击向量自动生成...

    【推荐】最新超全的渗透测试学习基础教程集合(84份).zip

    18.XSS跨站脚本攻击原理及代码攻防演示(一); 19.Powershell基础入门及常见用法(一); 20.Powershell基础入门及常见用法(二); …… 共84份,太多了就不一一列举了,喜欢的可以下载学习……

    Web安全深度剖析(张柄帅)

    第7章 XSS跨站脚本漏洞 129 7.1 XSS原理解析 129 7.2 XSS类型 130 7.2.1 反射型XSS 130 7.2.2 存储型XSS 131 7.2.3 DOM XSS 132 7.3 检测XSS 133 7.3.1 手工检测XSS 134 7.3.2 全自动检测XSS 134 7.4 XSS高级利用 ...

    超全的Web渗透自我学习资料合集(64篇).zip

    web渗透: 跨站脚本攻击(XSS) web渗透: HTTP Host头攻击 web渗透: SQL注入(上) web渗透: SQL注入(下) web渗透: XML注入攻击 web渗透: XXE外部实体注入 web渗透: 服务器端包含注入(SSI注入) web渗透: XPath...

    白帽子讲浏览器安全.钱文祥(带详细书签).pdf

    6.2.1 通用跨站脚本攻击 141 6.2.2 地址栏伪造 142 6.2.3 界面伪装 143 6.3 结合系统特性进行攻击 144 6.3.1 Android一例漏洞:使用Intent URL Scheme绕过Chrome SOP 144 6.3.2 iOS的一例漏洞:自动拨号泄露...

    web渗透系列教学下载共64份.zip

    web渗透--19--跨站脚本攻击(XSS).pdf web渗透--2--web渗透测试清单.pdf web渗透--20--HTTP Host头攻击.pdf web渗透--21--SQL注入(上).pdf web渗透--22--SQL注入(下).pdf web渗透--23--XML注入攻击.pdf web渗透...

    Web安全渗透测试基础入门篇视频.rar

    WEB安全架构分析及思路拓展wmv Web安全渗透测试基础...WEB伪造数据包进行XSS攻击演示wmv 基于S平台搭建ASP脚本解析环境wmv 基于SP脚本解析环境搭建.wmv 基于PHP脚本解析环境搭建.wmv 基于软件搭建ASP脚本解析环境.wmv

    适用于PHP的轻量级应用程序内Web应用程序防火墙-PHP开发

    对于每个请求,脚本都会解析参数以查找众所周知的攻击。 LiteWAF LiteWAF是一个简单的应用程序内Web应用程序防火墙。 它是一个PHP脚本,必须包含在要保护的每个页面的开头。 对于每个请求,脚本都会解析参数以查找...

    最新JQuery版本1.8

    开发者有时会忘记这一点,将不受信任的源或用户输入的字符串传递到jQuery,就可能导致脚本注入,使攻击者可以窃取cookies或破坏页面。 jQuery 1.8引入了一个新的方法“$.parseHTML”。它可以让你指定HTML字符串,...

    HtmlRuleSanitizer:建立在HTML Agility包顶部的基于规则HTML清理程序

    HtmlRuleSanitizer ... var sanitizer = HtmlSanitizer... 通过删除javascript和其他恶意HTML片段,防止跨站点脚本(XSS)攻击。 将HTML限制为简单标记,以便可以轻松转换为其他文档类型,而不必处理所有可能HTML标签。

    后台脚手架框架,包括用户管理、角色管理、权限系统等功能.zip

    基于Spring、Spring Boot、MyBatis、Shiro框架,,Spring Boot 快速开发平台,完善的 XSS 防范及脚本过滤,彻底杜绝 XSS 攻击,采用前后端分离技术实现 爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集...

Global site tag (gtag.js) - Google Analytics