`
ssxxjjii
  • 浏览: 950717 次
  • 性别: 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跨站脚本攻击在Java开发中防范的方法

    ### XSS跨站脚本攻击在Java开发中的防范方法 #### XSS攻击原理与分类 XSS(Cross-Site Scripting)跨站脚本攻击是一种常见的安全威胁,它利用Web应用程序的安全漏洞,将恶意脚本注入到合法的网页中,进而攻击最终...

    XSS跨站脚本攻击

    ### XSS跨站脚本攻击详解 #### 一、XSS跨站脚本攻击概述 XSS(Cross-Site Scripting)跨站脚本攻击是一种常见的Web应用安全威胁,其核心在于利用网站对用户输入数据的处理不当,允许攻击者注入恶意脚本到网页中,...

    XSS跨站脚本攻击剖析与防御.docx

    ### XSS跨站脚本攻击剖析与防御 #### 一、XSS攻击概述 跨站脚本(Cross Site Scripting,简称XSS)攻击是一种常见的Web应用程序安全漏洞,它允许攻击者将恶意脚本注入到看似可信的网站上。当用户浏览这些被注入...

    xss跨站脚本攻击

    ### XSS跨站脚本攻击详解 #### 一、XSS跨站脚本攻击概述 XSS(Cross-Site Scripting),即跨站脚本攻击,是一种常见的网络安全威胁,主要通过在受害者的浏览器环境中注入恶意脚本,从而实现对用户的攻击。这种攻击...

    XSS跨站脚本gj剖析与防御(完整版) pdf

    该文档可能会详细解析XSS攻击的工作原理,包括如何构造有效载荷,以及在各种类型的Web应用中如何实施这些攻击。此外,它也可能深入讨论XSS攻击的危害,如身份盗窃、会话劫持、钓鱼攻击等,并给出实际案例来展示攻击...

    XSS 跨站脚本攻击及防范

    ### XSS跨站脚本攻击及防范 #### 一、引言 随着互联网技术的迅猛发展,Web应用成为了人们日常生活中不可或缺的一部分。然而,这也为网络安全带来了新的挑战。XSS(Cross-Site Scripting,跨站脚本)攻击作为最常见...

    Xss跨站脚本攻击基础

    ### Xss跨站脚本攻击基础 #### 一、XSS攻击概述 XSS(Cross Site Scripting)攻击,即跨站脚本攻击,是一种常见的Web应用程序安全漏洞。这种攻击方式利用网页开发时的疏忽,允许攻击者将恶意脚本注入到网页中,当...

    第一节 XSS跨站脚本分类-01

    XSS 跨站脚本攻击是一种常见的 Web 应用程序安全漏洞,攻击者可以通过在 Web 页面中插入恶意 Script 代码来攻击用户。为了防止 XSS 攻击,需要了解 XSS 的分类和特点。 XSS 漏洞介绍 XSS 跨站脚本攻击(Cross Site...

    XSS跨站脚本攻击剖析与防御(目录)

    ### XSS跨站脚本攻击剖析与防御 #### 一、XSS攻击概述 **XSS**(Cross Site Scripting)即跨站脚本攻击,是一种常见的Web应用程序安全漏洞。这种攻击方式利用网页开发时的疏忽,允许攻击者往网页里插入恶意html代码...

    跨站脚本攻击字符过滤

    ### 跨站脚本攻击与字符过滤技术解析 #### 一、引言 随着互联网的飞速发展,网站已经成为人们日常生活中不可或缺的一部分。然而,在享受便捷的同时,我们也面临着各种网络安全威胁,其中“跨站脚本攻击”(Cross-...

    XSS跨站脚本gj剖析与防御

    XSS(Cross-Site Scripting)跨站脚本攻击是一种常见的网络安全漏洞,它允许攻击者在用户浏览器上执行恶意脚本,从而获取敏感信息、操纵用户界面或进行其他有害操作。这种攻击通常发生在Web应用程序中,因为它们未能...

    18.XSS跨站脚本攻击原理及代码攻防演示(一)1

    XSS(Cross-Site Scripting)跨站脚本攻击是一种常见的网络安全问题,它发生在攻击者通过在网页中注入恶意脚本,使得用户在不知情的情况下执行这些脚本,从而盗取用户数据或者控制用户浏览器的行为。XSS攻击主要分为...

    跨站脚本攻击(XSS)深度解析:从原理到防御

    跨站脚本攻击(XSS)是一种常见的网络安全威胁,它允许攻击者在目标用户的浏览器中注入恶意脚本,从而窃取敏感信息、操纵用户会话或进行其他恶意活动。本文将详细解释XSS的工作原理、类型、攻击手段以及如何进行有效...

    8、XSS 攻击的防御pdf资料

    XSS(跨站脚本攻击)是网络安全领域中一种常见的攻击方式,主要利用JavaScript来实施恶意行为。这种攻击之所以称为XSS,是因为原本的缩写CSS与层叠样式表(Cascading Style Sheets)冲突,因此改用XSS。XSS攻击的...

    XSS跨站总结

    XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的Web应用程序安全漏洞,它允许攻击者通过注入恶意脚本来攻击用户。这种攻击通常发生在用户浏览器上,利用的是用户对目标网站的信任。 - **定义**:XSS攻击是...

    跨站脚本攻击实例解析

    跨站脚本攻击(Cross-Site Scripting,简称XSS)是网络安全领域中常见的攻击手段之一,它利用了Web应用程序的不足,使攻击者能够注入恶意脚本到网页上,进而影响用户的安全。这种攻击方式可能导致用户数据泄露、会话...

    Web应用的安全攻防之跨站脚本攻击(XSS)

    ### Web应用的安全攻防之跨站脚本攻击(XSS) #### 跨站脚本(XSS)概述 跨站脚本攻击(Cross-Site Scripting,简称XSS)是Web应用程序中最常见的安全漏洞之一。它允许攻击者将恶意脚本注入到看似可信的网站中。当用户...

Global site tag (gtag.js) - Google Analytics