介绍
跨站脚本(又称XSS)是一种漏洞,利用该漏洞黑客可以操纵合法用户与web应用程序之间的交互。攻击者利用此漏洞可以绕过同源策略,在合法用户完全不知情的情况下执行任意的恶意操作,包括获得对其数据的访问权。在受害用户拥有应用程序访问特权的情况下,攻击者还可能使用XSS来夺取对应用程序的控制。
XSS攻击通常发生在web应用程序中,通常以web请求的形式接收到包含攻击代码的数据,这些恶意数据在不经过验证的情况下反馈到用户的HTTP响应中。
XSS攻击一般可分为以下三类。
反射型XSS
反射型 XSS 是指应用程序通过 Web 请求获取不可信赖的数据,并在未检验数据是否存在恶意代码的情况下,将其发送给用户。反射型 XSS 一般可以由攻击者构造带有恶意代码参数的 URL 来实现,在构造的URL 地址被打开后,其中包含的恶意代码参数被浏览器解析和执行。这种攻击的特点是非持久化,必须用户点击包含恶意代码参数的链接时才会触发。 其实XSS就类似于 SQL 注入,只不过一个是针对数据库,一个是针对 HTML ,通过你提交的数据,实现反射型 XSS 可以比较容易地修改用户数据、窃取用户信息。
另一种途径是攻击者通过电子邮件传递恶意URL给受害者,从而欺骗用户点击恶意链接。注入的代码传输到存在漏洞的网站,该网站将有效的攻击payload反射给用户的浏览器。因为这些代码来自一个“受信任的”服务器,然后浏览器就执行了恶意代码。
存储型XSS
在存储型XSS攻击中,注入的脚本作为合法内容存储在目标应用程序中,例如论坛中的消息或博客文章中的评论。注入的代码存储在数据库中,并在接收到检索请求时发送给用户,从而在受害者的浏览器中执行有效的攻击负载
基于DOM的XSS
当页面中的JavaScript从HTML中的源代码中获取用户提供的数据时比如document.location 并将其传递给允许运行JavaScript代码的JavaScript函数,如innerHTML(),就有可能会出现基于DOM的XSS漏洞。另一种经典的攻击途径是将有效载攻击荷传递给受害者(例如,电子邮件或伪造的合法网站),从而欺骗用户访问恶意链接,恶意代码将立即在用户的浏览器中执行。
影响及危害
XSS攻击会导致用户的会话cookie被泄露,从而允许攻击者劫持用户的会话并接管帐户。即使使用HTTPOnly来保护cookie,攻击者仍然可以在受影响网站的上下文中伪装成用户执行恶意操作。
与OWASP Top 10中的其他严重漏洞一样,XSS攻击可以导致用户系统的遭受到严重的破坏。正如前文所述,如果黑客劫持了持有“keys to the kingdom”的用户,即拥有了对应用程序/管理员权限的特权访问,结果可能是毁灭性的
如何防护
通过在服务器端执行适当的验证和转义可以减轻XSS攻击。还可以对不可信的HTML上下文类型的数据在执行输出时进行编码(例如使用转义语法)。
输入验证
精确匹配:只接受有限的已知列表中的值。(全字段匹配的白名单)
允许列表:如果无法创建包含所有可能值的列表,则只接受已知的数据并拒绝所有意外输入。(正则表达式的白名单)
拒绝列表:如果允许列表方法不可用,拒绝所有已知的错误值。(黑名单)
输出编码
输出编码用于将不可信的输入转换为安全形式,在这种形式中,输入的内容将仅仅被当作数据显示给用户,而不会被看作代码被浏览器执行。输出编码的操作是在数据离开应用程序到下游组件时才执行。下表列出了可能使用不可信输入的下游上下文:
Context | Code | Encoding |
HTML Body | <div>USER-CONTROLLED-DATA</div> | HTML Encoding |
HTML Attribute | <input type="text" value="USER-CONTROLLED-DATA"> | HTML Attribute Encoding |
URL Parameter | <a href="/search?value=USER-CONTROLLED-DATA">Search</a> | URL Encoding |
CSS | <div style="width: USER-CONTROLLED-DATA;">Selection</div> | CSS Hex Encoding |
JavaScript | <script>var lang ='USER-CONTROLLED-DATA';</script> | JavaScript Encoding |
下表详细列出了预防XSS所需的输出编码方法:
ncoding Type | Encoding Mechanism |
HTML Entity Encoding | Convert &to & |
HTML Attribute Encoding | Except for alphanumeric characters, escape all characters with the HTML Entity &#xHH; format including spaces. (HH = Hex Value) |
URL Encoding | For standard percent encoding see here. URL encoding should only be used to encode parameter values, not the entire URL or path fragments of a URL. |
JavaScript Encoding | Except for alphanumeric characters, escape all characters with the \uXXXX unicode escaping format (XX = Integer) |
CSS Hex Encoding | CSS escaping supports \XX and \XXXXXX. Using a two-character escape can cause problems if the next character continues the escape sequence. There are two solutions: |
深度防御
内容安全策略 (CSP)
内容安全策略(CSP)是一种浏览器机制,它可以为web应用程序的客户端资源(如JavaScript、CSS、图像等)创建源允许列表。CSP通过一个特殊的HTTP头指示浏览器只执行或呈现来自这些源的资源。
例如:
Content-Security-Policy: default-src: 'self'; script-src: 'self' static.domain.tld
上面的CSP将指示web浏览器仅从页面的原始文件和来自static.domain.tld的JavaScript源代码文件加载资源。有关内容安全策略的更多详细信息,包括它的功能以及如何使用它,请参阅https://content-security-policy.com/。
X-XSS-Protection Header
这个HTTP响应头启用了一些web浏览器内置的跨站点脚本(XSS)过滤器。通常情况下,header都是默认启用的,所以它的作用是在用户禁用某个特定网站时重新启用过滤器。
Content Types
为了防止嵌入的非HTML HTTP响应数据被危险地解析为HTML或JavaScript的数据,建议总是在HTTP响应中发送Content-Type报头,以确保浏览器按照预期的方式解析它。
Modern Frameworks
新的JavaScript框架(如AngularJS, ReactJS)或服务器端模板系统(如Go模板)都有强大的内置保护来防止反射跨站点脚本。