跨站脚本是应用程序安全开源基金会 (OWASP) 前 10 名中第二个最普遍的问题——它存在于大约 2/3 的所有应用程序中。虽然自动化工具可以发现其中的一些问题,但也有一些旨在检测和利用这些漏洞的自动化工具。
什么是跨站脚本?
当数据通过不受信任的来源(如 Web 请求)进入 Web 应用程序并未经验证就发送给用户时,就会发生 XSS 攻击。
XSS 会导致脚本在用户的浏览器中执行,从而导致会话被劫持、网站篡改以及将用户重定向到恶意站点。
从本质上讲,攻击者将恶意代码输入到用户输入的部分中,服务器希望该部分是数据(但实际上是为了执行而设计的代码)。
如果处理不当,恶意代码可能会突破“数据平面”并作为正常代码(“控制平面”)执行。
我们可以将大多数 XSS 攻击分为两类:存储的和反射的。第三种不太常见,称为基于 DOM 的 XSS。
当数据通过不受信任的来源进入并发送给用户(在动态内容中)而没有检查恶意内容时,就会发生任何 XSS 攻击。恶意内容可以是 JavaScript、Flash、HTML 或浏览器能够执行的任何其他代码。
反射型 XSS(影响:中等)
这是最基本的 XSS 类型,其中应用程序接收数据,然后以不安全的方式将这些数据包含在对用户的响应中。
例如,如果攻击者说服用户单击此网络钓鱼链接:
http://legitwebsite.com/message=<script>恶意代码</script>
如果合法站点不处理数据而只是将其返回给用户,则用户的浏览器将执行恶意代码。
存储型 XSS(影响:严重)
当注入永久存储在目标的服务器上时,就会发生存储型 XSS,例如论坛或评论部分、数据库中的消息等。从本质上讲,这意味着该漏洞会影响站点/应用程序的每个访问者。
例如,如果站点允许用户发表评论,然后显示他们的评论,则用户可以输入以下内容:
<p><script>恶意代码</script></p>
如果站点没有适当地检查用户输入,则可能会导致脚本为看到此消息的任何其他用户执行。
基于DOM的XSS/客户端XSS(影响:中等)
反射型 XSS 和存储型 XSS 与基于 DOM 的最大区别在于攻击的注入位置。
反射和存储 XSS 是服务器端问题,而基于 DOM 是客户端(浏览器)端问题。基于 DOM 的 XSS 发生在 DOM(文档对象模型)中,而不是作为 HTML 的一部分。
这种攻击不是在页面中插入恶意代码,而是允许加载合法页面,然后利用用户输入向页面添加 HTML,执行恶意脚本。这利用了客户端生成的 HTML 数量不断增加的优势。
例如,攻击者可以通过社会工程使受害者点击恶意链接(例如 http://www.legitimatewebsite.com/contact#<script>malicious code</script>)。该网站将收到对该页面的合法请求,但不会收到恶意片段(因为浏览器不会向站点的服务器发送 # 字符后的任何内容)。受害者会看到合法网站,但受害者的浏览器也会执行恶意脚本。
由于这种攻击的工作方式,服务器端保护不会阻止它,因为恶意代码根本没有发送到服务器。
相反,防止这种攻击需要确保 JavaScript 不会以不安全的方式解释 URI 片段(统一资源标识符 - URI 标识指定位置的资源,例如 URL)。
XSS 攻击的缓解措施
有效缓解 XSS 攻击需要结合以下措施,当您将它们结合使用时,可以提供强大的 XSS 防御。
避免在指定位置以外的任何地方插入用户提供的/不受信任的数据
这是第一个也是最重要的规则。编码、转义、验证和过滤输入极其困难且非常复杂。
限制某人可以输入不可信数据的位置要容易得多。最安全的假设是所有不受信任的数据都是恶意的。
验证/过滤输入
理想情况下,所有输入都应根据可接受的值列表进行验证。
编码输出
任何用户输入的数据都应该被编码以防止它被读取为活动的。这可能需要 CSS、JavaScript、URL 和/或 HTML 编码。
确保输出在任何暴露的点都被编码尤为重要,因为相同的数据可以存储并显示在多个位置。
谨慎选择框架
使用提供自动转义功能的框架(如 Go 模板)或具有针对 XSS 的本机防御(如 .NET 的请求验证)的框架。
设置 HttpOnly 标志
XSS 攻击通常使用 JavaScript 来窃取会话 cookie(而普通的 Web 应用程序很少需要使用 JavaScript 来访问会话 cookie)。因此,设置 HttpOnly 标志可以保护会话 cookie 免受攻击者的攻击,同时不会限制正常行为。大多数浏览器都支持设置这个标志。
使用响应头
与 HttpOnly 标志类似,任何不应包含 HTML 或 JavaScript 的 HTTP 响应都可以利用“Content-Type”和“X-Content-Type-Options”标头来确保浏览器仅以预期的方式解释响应。
对开发人员进行安全教育
专门针对开发人员的教育,例如将应用程序安全团队成员与开发人员配对的“安全冠军”计划,很重要。它们可以帮助开发人员了解安全漏洞(如 XSS)以及如何防止它们。
制定内容安全政策
内容安全策略 (CSP) 可以帮助您检测和缓解 XSS 和其他数据注入攻击。
他们为受信任内容的来源设置了许可名单,并且只能应用于敏感页面(如支付页面),或者理想情况下,应用于整个网站。如果内容是从不应加载的页面加载的,他们甚至可以提供通知。
它们相当容易部署 - 只需将 Content-Security-Policy HTTP 标头添加到网页和任何适当的指令即可。
该CSP提琴手扩展可以帮助您生成一个基准CSP。该工具将围绕浏览器提交的报告构建策略,创建可更改的基线策略。
此外,您可以使用由 Troy Hunt 和 Scott Helme 运行的Report URI来获取有关 CSP 违规的警报,以便更主动地监控您的站点。
通常,策略由一系列指令组成,这些指令将描述一种资源或区域的策略。这些指令之一,子资源完整性检查,用于确保浏览器验证第三方内容(来自 CDN 之类的来源)是在没有被操纵的情况下交付的。
本质上,提供的加密哈希必须与加载的文件匹配。如果黑客修改了第三方的内容,该站点将不会加载恶意内容。
问题是,如果内容提供者更新文件或进行合法更改,内容也不会加载(因为哈希值已更改)。
解决此问题的主要方法是利用版本化的 JavaScript 资源,例如 chatbot_0.1.23.js,而不是 chatbot.js。这是一般的最佳实践,也保证了JS文件发生变化时服务的连续性。
虽然浏览器并不普遍支持此功能,但对于那些缺少该功能的浏览器,使用它不会破坏站点(它只是不会利用该技术)。