Cross-SiteScripting:DOM跨站点脚本:DOM
Abstract:
jsmind.js 中的⽅法 onreadystatechange() 向第 781 ⾏的 Web 浏览器发送⾮法数据,从⽽导致浏览器执⾏恶意代码。
Explanation:
Cross-Site Scripting (XSS) 漏洞在以下情况下发⽣:
1. 数据通过⼀个不可信赖的数据源进⼊ Web 应⽤程序。对于基于 DOM 的 XSS,将从 URL 参数或浏览器中的其他值读取数据,并使⽤客户端代码将其重新写⼊该页⾯。对于 Reflected XSS,不可信赖的源通常为 Web 请求,⽽对于 Persisted(也称为 Stored)XSS,该源通常为数据库或其他后端数据存储。
2. 未检验包含在动态内容中的数据,便将其传送给了 Web ⽤户。对于基于 DOM 的 XSS,任何时候当受害⼈的浏览器解析 HTML 页⾯时,恶意内容都将作为 DOM(⽂档对象模型)创建的⼀部分执⾏。
传送到 Web 浏览器的恶意内容通常采⽤ JavaScript 代码⽚段的形式,但也可能会包含⼀些 HTML、Flash 或者其他任意⼀种可以被浏览器执⾏的代码。基于 XSS 的攻击⼿段花样百出,⼏乎是⽆穷⽆尽的,
但通常它们都会包含传输给攻击者的私⼈数据(如 Cookie 或者其他会话信息)。在攻击者的控制下,指引受害者进⼊恶意的⽹络内容;或者利⽤易受攻击的站点,对⽤户的机器进⾏其他恶意操作。
例 1:下⾯的 JavaScript 代码⽚段可从 URL 中读取雇员 ID eid,并将其显⽰给⽤户。
<SCRIPT>
var pos=document.URL.indexOf("eid=")+4;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
⽰例 2:考虑使⽤ HTML 表单:
<div id="myDiv">
Employee ID: <input type="text" id="eid"><br>
...
<button>Show results</button>
</div>
<div id="resultsDiv">
...
</div>
下⾯的 jQuery 代码⽚段可从表单中读取雇员 ID,并将其显⽰给⽤户。
$(document).ready(function(){
$("#myDiv").on("click", "button", function(){
var eid = $("#eid").val();
$("resultsDiv").append(eid);
...
});
});
如果雇员 ID eid 只包含标准的字母数字⽂本,此代码就会正常运⾏。如果 eid ⾥有包含元字符或源代码中的值,那么 Web 浏览器就会像显⽰ HTTP 响应那样执⾏代码。
起初,这个例⼦似乎是不会轻易遭受攻击的。毕竟,有谁会输⼊导致恶意代码的 URL,并且还在⾃⼰的电脑上运⾏呢?真正的危险在于攻击者会创建恶意的 URL,然后采⽤电⼦邮件或者社会⼯程的欺骗⼿段诱使受害者访问此 URL 的链接。当受害者单击这个链接时,他们不知不觉地通过易受攻击的⽹络应⽤程序,将恶意内容带到了⾃⼰的电脑中。这种对易受攻击的 Web 应⽤程序进⾏盗取的机制通常被称为反射式 XSS。
正如例⼦中所显⽰的,XSS 漏洞是由于 HTTP 响应中包含了未验证的数据代码⽽引起的。受害者遭受 XSS 攻击的途径有三种:
— 系统从 HTTP 请求中直接读取数据,并在 HTTP 响应中返回数据。当攻击者诱使⽤户为易受攻击的 Web 应⽤程序提供危险内容,⽽这些危险内容随后会反馈给⽤户并在 Web 浏览器中执⾏,就会发⽣反射式 XSS 盗取。发送恶意内容最常⽤的⽅法是,把恶意内容作为⼀个参数包含在公开发表的 URL 中,或者通过电⼦邮件直接发送给受害者。以这种⼿段构造的 URL 构成了多种“⽹络钓鱼”(phishing) 阴谋的核⼼,攻击者借此诱骗受害者访问指向易受攻击站点的 URL。站点将攻击者的内容反馈给受害
者以后,便会执⾏这些内容,接下来会把⽤户计算机中的各种私密信息(⽐如包含会话信息的 cookie)传送给攻击者,或者执⾏其他恶意活动。
— 应⽤程序将危险数据存储在数据库或其他可信赖的数据存储器中。这些危险数据随后会被回写到应⽤程序中,并包含在动态内容中。Persistent XSS 盗取发⽣在如下情况:攻击者将危险内容注⼊到数据存储器中,且该存储器之后会被读取并包含在动态内容中。从攻击者的⾓度看,注⼊恶意内容的最佳位置莫过于⼀个⾯向许多⽤户,尤其是相关⽤户显⽰的区域。相关⽤户通常在应⽤程序中具备较⾼的特权,或相互之间交换敏感数据,这些数据对攻击者来说有利⽤价值。如果某⼀个⽤户执⾏了恶意内容,攻击者就有可能以该⽤户的名义执⾏某些需要特权的操作,或者获得该⽤户个⼈所有的敏感数据的访问权限。
— 应⽤程序之外的数据源将危险数据储存在⼀个数据库或其他数据存储器中,随后这些危险数据被当作可信赖的数据回写到应⽤程序中,并储存在动态内容中。
Instance ID: 069BCA4EE68E819122DC50C9D7E3077E
Priority Metadata Values:
IMPACT: 5.0
LIKELIHOOD: 5.0
Legacy Priority Metadata Values:
SEVERITY: 4.0
CONFIDENCE: 5.0
Remediation Effort: 1.0
Recommendations:
针对 XSS 的解决⽅法是,确保在适当位置进⾏验证,并检验其属性是否正确。
由于 XSS 漏洞出现在应⽤程序的输出中包含恶意数据时,因此,合乎逻辑的做法是在数据流出应⽤程序的前⼀刻对其进⾏验证。然⽽,由于 Web 应⽤程序常常会包含复杂⽽难以理解的代码,⽤以⽣成动态内容,因此,这⼀⽅法容易产⽣遗漏错误(遗漏验证)。降低这⼀风险的有效途径是对 XSS 也执⾏输⼊验证。
write的返回值由于 Web 应⽤程序必须验证输⼊信息以避免其他漏洞(如 SQL Injection),因此,⼀种相对简单的
解决⽅法是,加强⼀个应⽤程序现有的输⼊验证机制,将 XSS 检测包括其中。尽管有⼀定的价值,但 XSS 输⼊验证并不能取代严格的输出验证。应⽤程序可能通过共享的数据存储或其他可信赖的数据源接受输⼊,⽽该数据存储所接受的输⼊源可能并未执⾏适当的输⼊验证。因此,应⽤程序不能间接地依赖于该数据或其他任意数据的安全性。这就意味着,避免 XSS 漏洞的最佳⽅法是验证所有进⼊应⽤程序以及由应⽤程序传送⾄⽤户端的数据。
针对 XSS 漏洞进⾏验证最安全的⽅式是,创建⼀份安全字符⽩名单,允许其中的字符出现在 HTTP 内容中,并且只接受完全由这些经认可的字符组成的输⼊。例如,有效的⽤户名可能仅包含字母数字字符,电话号码可能仅包含 0-9 的数字。然⽽,这种解决⽅法在 Web 应⽤程序中通常是⾏不通的,因为许多字符对浏览器来说都具有特殊的含义,在写⼊代码时,这些字符仍应被视为合法的输⼊,⽐如⼀个 Web 设计版就必须接受带有 HTML 代码⽚段的输⼊。
更灵活的解决⽅法称为⿊名单⽅法,但其安全性较差,这种⽅法在进⾏输⼊之前就有选择地拒绝或避免了潜在的危险字符。为了创建这样⼀个列表,⾸先需要了解对于 Web 浏览器具有特殊含义的字符集。虽然 HTML 标准定义了哪些字符具有特殊含义,但是许多 Web 浏览器会设法更正 HTML 中的常见错误,并可能在特定的上下⽂中认为其他字符具有特殊含义,这就是我们不⿎励使⽤⿊名单作为阻⽌ XSS 的⽅法的原因。卡耐基梅隆⼤学 (Carnegie Mellon University) 软件⼯程学院 (Software Engineering Institute) 下属的 CERT(R) (CERT(R) Coordination Center) 合作中⼼提供了有关各种上下
⽂中认定的特殊字符的具体信息 [1]:
在有关块级别元素的内容中(位于⼀段⽂本的中间):
- "<" 是⼀个特殊字符,因为它可以引⼊⼀个标签。
- "&" 是⼀个特殊字符,因为它可以引⼊⼀个字符实体。
- ">" 是⼀个特殊字符,之所以某些浏览器将其认定为特殊字符,是基于⼀种假设,即该页的作者本想在前⾯添加⼀个 "<",却错误地将其遗漏了。
下⾯的这些原则适⽤于属性值:
-对于外加双引号的属性值,双引号是特殊字符,因为它们标记了该属性值的结束。
-对于外加单引号的属性值,单引号是特殊字符,因为它们标记了该属性值的结束。
-对于不带任何引号的属性值,空格字符(如空格符和制表符)是特殊字符。
- "&" 与某些特定变量⼀起使⽤时是特殊字符,因为它引⼊了⼀个字符实体。
例如,在 URL 中,搜索引擎可能会在结果页⾯内提供⼀个链接,⽤户可以点击该链接来重新运⾏搜索。可以将这⼀⽅法运⽤于编写 URL 中的搜索查询语句,这将引⼊更多特殊字符:
-空格符、制表符和换⾏符是特殊字符,因为它们标记了 URL 的结束。
- "&" 是特殊字符,因为它可引⼊⼀个字符实体或分隔 CGI 参数。
-⾮ ASCII 字符(即 ISO-8859-1 编码表中所有⾼于 128 的字符)不允许出现在 URL 中,因此在此上下⽂中也被视为特殊字符。
-在服务器端对在 HTTP 转义序列中编码的参数进⾏解码时,必须过滤掉输⼊中的 "%" 符号。例如,当输⼊中出现
"%68%65%6C%6C%6F" 时,只有从输⼊的内容中过滤掉 "%",上述字符串才能在⽹页上显⽰为 "hello"。
在 <SCRIPT> </SCRIPT> 的正⽂内:
- 如果可以将⽂本直接插⼊到已有的脚本标签中,应该过滤掉分号、省略号、中括号和换⾏符。
服务器端脚本:
-如果服务器端脚本会将输⼊中的感叹号 (!) 转换成输出中的双引号 ("),则可能需要对此进⾏更多过滤。
其他可能出现的情况:
-如果攻击者在 UTF-7 中提交了⼀个请求,那么特殊字符 "<" 可能会显⽰为 "+ADw-",并可能会绕过过滤。如果输出包含在没有确切定义编码格式的⽹页中,有些浏览器就会设法根据内容⾃动识别编码(此处采⽤ UTF-7 格式)。
⼀旦在应⽤程序中确定了针对 XSS 攻击执⾏验证的正确要点,以及验证过程中要考虑的特殊字符,下⼀个难点就是定义验证过程中处理各种特殊字符的⽅式。如果应⽤程序认定某些特殊字符为⽆效输⼊,那么您可以拒绝任何带有这些⽆效特殊字符的输⼊。第⼆种选择就是采⽤过滤⼿段来删除这些特殊字符。然⽽,过滤的负⾯作⽤在于,过滤内容的显⽰将发⽣改变。在需要完整显⽰输⼊内容的情况下,过滤的这种负⾯作⽤可能是⽆法接受的。
如果必须接受带有特殊字符的输⼊,并将其准确地显⽰出来,验证机制⼀定要对所有特殊字符进⾏编码,以便删除其具有的含义。官⽅的HTML 规范 [2] 提供了特殊字符对应的 ISO 8859-1 编码值的完整列表。
许多应⽤程序服务器都试图避免应⽤程序出现 Cross-Site Scripting 漏洞,具体做法是为负责设置特定 HTTP 响应内容的函数提供各种实现⽅式,以检验是否存在进⾏ Cross-Site Scripting 攻击必需的字符。不要依赖运⾏应⽤程序的服务器,以此确保该应⽤程序的安全。开发了某个应⽤程序后,并不能保证在其⽣命周期中它会在哪些应⽤程序服务器中运⾏。由于标准和已知盗取⽅式的演变,我们不能保证应⽤程序服务器也会保持同步。
Tips:
1. HPE Security 安全编码规则包将就 SQL Injection 和 Access Control 提出警告:当把不可信赖的数据写⼊数据库时,数据库将出现问题,并且会将数据库当作不可信赖的数据的来源,这会导致 XSS 漏洞。如果数据库在您的环境中是可信赖的资源,则使⽤⾃定义筛选器筛选出包含 DATABASE 污染标志或来⾃数据库源的数据流问题。尽管如此,对所有从数据库中读取的内容进⾏验证仍然是较好的做法。
2. 虽然使⽤ URL 对不可信数据进⾏编码可以防⽌许多 XSS 攻击,但部分浏览器(尤其是 Internet Explorer 6 和 7 以及其他浏览器)在将数据传递给 JavaScript 解释器之前,会⾃动在⽂档对象模型 (DOM) 中的特定位置对其内容进⾏解码。为了反映出其危险之处,规则包不再认为 URL 编码例程⾜以防御 cross-site scripting 攻击。如果对数据值进⾏ URL 编码并随后输出,HPE Security Fortify 将会报告存在 Cross-Site Scripting: Poor Validation 漏洞。
References:
[1] Understanding Malicious Content Mitigation for Web Developers, CERT,
[2] HTML 4.01 Specification, W3,
[3] Standards Mapping - Common Weakness Enumeration, CWE ID 79, CWE ID 80
[4] Standards Mapping - FIPS200, SI
[5] Standards Mapping - NIST Special Publication 800-53 Revision 4, SI-10 Information Input Validation (P1)
[6] Standards Mapping - OWASP Mobile Top 10 Risks 2014, M7 Client Side Injection
[7] Standards Mapping - OWASP Top 10 2004, A4 Cross Site Scripting
[8] Standards Mapping - OWASP Top 10 2007, A1 Cross Site Scripting (XSS)
[9] Standards Mapping - OWASP Top 10 2010, A2 Cross-Site Scripting (XSS)
[10] Standards Mapping - OWASP Top 10 2013, A3 Cross-Site Scripting (XSS)
[11] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1, Requirement 6.5.4
[12] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2, Requirement 6.3.1.1, Requirement 6.5.1
[13] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0, Requirement 6.5.7
[14] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0, Requirement 6.5.7
[15] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1, Requirement 6.5.7
[16] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2, Requirement 6.5.7
[17] Standards Mapping - SANS Top 25 2009, Insecure Interaction - CWE ID 079
[18] Standards Mapping - SANS Top 25 2010, Insecure Interaction - CWE ID 079
[19] Standards Mapping - SANS Top 25 2011, Insecure Interaction - CWE ID 079
[20] Standards Mapping - Security Technical Implementation Guide Version 3.1, APP3510 CAT I, APP3580 CAT I
[21] Standards Mapping - Security Technical Implementation Guide Version 3.10, APP3510 CAT I, APP3580 CAT I
[22] Standards Mapping - Security Technical Implementation Guide Version 3.4, APP3510 CAT I, APP3580 CAT I
[23] Standards Mapping - Security Technical Implementation Guide Version 3.5, APP3510 CAT I, APP3580 CAT I
[24] Standards Mapping - Security Technical Implementation Guide Version 3.6, APP3510 CAT I, APP3580 CAT I
[25] Standards Mapping - Security Technical Implementation Guide Version 3.7, APP3510 CAT I, APP3580 CAT I
[26] Standards Mapping - Security Technical Implementation Guide Version 3.9, APP3510 CAT I, APP3580 CAT I
[27] Standards Mapping - Security Technical Implementation Guide Version 4.1, APSC-DV-002490 CAT I, APSC-DV-002560 CAT I
[28] Standards Mapping - Web Application Security Consortium 24 + 2, Cross-Site Scripting
[29] Standards Mapping - Web Application Security Consortium Version 2.00, Cross-Site Scripting (WASC-08)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论