XSS 跨站脚本注入

什么是跨站脚本(XSS)?

跨站点脚本(也称为 XSS)是一种 Web 安全漏洞,允许攻击者破坏用户与易受攻击的应用程序的交互。它允许攻击者绕过旨在将不同网站彼此隔离的同源策略。跨站点脚本漏洞通常允许攻击者伪装成受害者用户,执行用户能够执行的任何操作,并访问用户的任何数据。如果受害者用户在应用程序中拥有特权访问权限,那么攻击者可能能够完全控制应用程序的所有功能和数据。

XSS 是如何工作的?

跨站点脚本通过操纵易受攻击的网站来工作,以便将恶意 JavaScript 返回给用户。当恶意代码在受害者的浏览器中执行时,攻击者可以完全破坏他们与应用程序的交互。

XSS 概念证明

你可以通过注入一个有效载荷来确认大多数类型的 XSS 漏洞,该载荷会导致你自己的浏览器执行一些任意的 JavaScript。长期以来alert(),将此函数用于此目的一直是一种常见做法,因为它很短、无害,并且在成功调用时很难错过。事实上,您通过调用alert()模拟受害者的浏览器来解决我们的大多数 XSS 实验室。

XSS 攻击有哪些类型?

XSS 攻击主要分为三种类型。这些是:

反射型 XSS,其中恶意脚本来自当前的 HTTP 请求。
存储的 XSS,其中恶意脚本来自网站的数据库。
基于 DOM 的 XSS,该漏洞存在于客户端代码而不是服务器端代码中。

反射式跨站脚本

反射型 XSS是最简单的跨站脚本。当应用程序在 HTTP 请求中接收数据并以不安全的方式在即时响应中包含该数据时,就会出现这种情况。

下面是一个反射型 XSS漏洞的简单示例:

https://insecure-website.com/status?message=All+is+well.

<p>Status: All is well.</p>

该应用程序不会对数据执行任何其他处理,因此攻击者可以轻松构建这样的攻击:

https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>

<p>Status: <script>/* Bad stuff here... */</script></p>

如果用户访问攻击者构建的 URL,则攻击者的脚本将在用户浏览器中执行,在该用户与应用程序的会话上下文中。此时,脚本可以执行任何操作,并检索用户有权访问的任何数据

存储跨站脚本

当应用程序从不受信任的来源接收数据并以不安全的方式在其后续 HTTP 响应中包含该数据时,就会出现存储型 XSS(也称为持久性或二阶 XSS)。

有问题的数据可能通过 HTTP 请求提交给应用程序;例如,对博客文章的评论、聊天室中的用户昵称或客户订单上的联系方式。在其他情况下,数据可能来自其他不受信任的来源;例如,显示通过 SMTP 接收的消息的网络邮件应用程序、显示社交媒体帖子的营销应用程序或显示来自网络流量的数据包数据的网络监控应用程序。

这是一个存储型 XSS漏洞的简单示例。留言板应用程序允许用户提交消息,这些消息会显示给其他用户:

<p>Hello, this is my message!</p>

该应用程序不会对数据执行任何其他处理,因此攻击者可以轻松发送攻击其他用户的消息:

<p><script>/* Bad stuff here... */</script></p>

基于DOM的跨站脚本

基于 DOM 的 XSS(也称为DOM XSS)在应用程序包含一些客户端 JavaScript 时出现,这些 JavaScript 以不安全的方式处理来自不受信任来源的数据,通常是将数据写回 DOM。

在以下示例中,应用程序使用一些 JavaScript 从输入字段读取值并将该值写入 HTML 中的元素:

var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'You searched for: ' + search;

如果攻击者可以控制输入字段的值,他们就可以很容易地构造一个恶意值来执行自己的脚本:

You searched for: <img src=1 one rror='/* Bad stuff here... */'>

在典型情况下,输入字段将从 HTTP 请求的一部分填充,例如 URL 查询字符串参数,允许攻击者以与反射 XSS 相同的方式使用恶意 URL 进行攻击。

XSS 可以用来做什么?

利用跨站点脚本漏洞的攻击者通常能够:

  • 冒充或伪装成受害者用户。
  • 执行用户能够执行的任何操作。
  • 读取用户能够访问的任何数据。
  • 捕获用户的登录凭据。
  • 对网站进行虚拟篡改。
  • 将特洛伊木马功能注入网站。

XSS 漏洞的影响

XSS 攻击的实际影响通常取决于应用程序的性质、其功能和数据,以及受感染用户的状态。例如:

  • 在宣传册应用程序中,所有用户都是匿名的,所有信息都是公开的,影响通常很小。
  • 在保存敏感数据(例如银行交易、电子邮件或医疗记录)的应用程序中,影响通常会很严重。
  • 如果受感染用户在应用程序中具有提升的权限,那么影响通常很严重,允许攻击者完全控制易受攻击的应用程序并危害所有用户及其数据。

如何查找和测试 XSS 漏洞

使用 Burp Suite 的Web 漏洞扫描器可以快速可靠地找到绝大多数 XSS 漏洞。

手动测试反射和存储的 XSS 通常涉及向应用程序的每个入口点提交一些简单的唯一输入(例如短的字母数字字符串),识别在 HTTP 响应中返回提交输入的每个位置,并单独测试每个位置以确定适当制作的输入是否可用于执行任意 JavaScript。通过这种方式,您可以确定XSS 发生的上下文并选择合适的负载来利用它。

手动测试由 URL 参数引起的基于 DOM 的 XSS 涉及类似的过程:在参数中放置一些简单的唯一输入,使用浏览器的开发人员工具在 DOM 中搜索此输入,并测试每个位置以确定它是否可利用。但是,其他类型的 DOM XSS 更难检测。要在非基于 URL 的输入(例如)或非基于 HTML 的接收器(例如)中查找基于 DOM 的漏洞,没有替代检查 JavaScript 代码的方法,这可能非常耗时。Burp Suite 的 Web 漏洞扫描器结合了 JavaScript 的静态和动态分析,可以可靠地自动检测基于 DOM 的漏洞。 document.cookiesetTimeout

内容安全政策

内容安全策略 ( CSP ) 是一种浏览器机制,旨在减轻跨站点脚本和其他一些漏洞的影响。如果使用 CSP 的应用程序包含类似 XSS 的行为,则 CSP 可能会阻碍或阻止对该漏洞的利用。通常,可以绕过 CSP 以利用底层漏洞。

悬空标记注入

悬空标记注入是一种技术,可用于在由于输入过滤器或其他防御而无法进行完整的跨站点脚本攻击的情况下捕获跨域数据。它通常可用于捕获其他用户可见的敏感信息,包括可用于代表用户执行未经授权的操作的 CSRF 令牌。

如何防止 XSS 攻击

在某些情况下,防止跨站点脚本编写是微不足道的,但根据应用程序的复杂性及其处理用户可控数据的方式,可能会更加困难。

一般来说,有效防止XSS漏洞很可能涉及以下措施的组合:

  • 到达时过滤输入。在收到用户输入时,根据预期或有效输入尽可能严格地进行过滤。
  • 对输出的数据进行编码。在 HTTP 响应中输出用户可控数据时,对输出进行编码以防止其被解释为活动内容。根据输出上下文,这可能需要应用 HTML、URL、JavaScript 和 CSS 编码的组合。
  • 使用适当的响应头。为了防止不打算包含任何 HTML 或 JavaScript 的 HTTP 响应中的 XSS,您可以使用Content-Type和X-Content-Type-Options标头来确保浏览器以您想要的方式解释响应。
  • 内容安全政策。作为最后一道防线,您可以使用内容安全策略 (CSP) 来降低仍然发生的任何 XSS 漏洞的严重性。

关于跨站脚本的常见问题

  1. XSS 漏洞有多常见?
    XSS 漏洞非常普遍,XSS 可能是最常出现的 Web 安全漏洞。
  2. XSS 攻击有多常见?
    很难获得关于真实世界 XSS 攻击的可靠数据,但与其他漏洞相比,它的利用频率可能较低。
  3. XSS 和 CSRF 有什么区别?
    XSS 涉及导致网站返回恶意 JavaScript,而 CSRF 涉及诱导受害用户执行他们不打算执行的操作。
  4. XSS 和 SQL 注入有什么区别?
    XSS 是针对其他应用程序用户的客户端漏洞,而 SQL 注入是针对应用程序数据库的服务器端漏洞。
  5. 如何防止 PHP 中的 XSS?
    使用允许字符的白名单过滤您的输入,并使用类型提示或类型转换。使用htmlentities和ENT_QUOTES为 HTML 上下文转义您的输出,或为 JavaScript 上下文转义 JavaScript Unicode 转义。
  6. 如何在 Java 中防止 XSS?
    使用允许字符的白名单过滤您的输入,并使用 Google Guava 等库对 HTML 上下文的输出进行 HTML 编码,或对 JavaScript 上下文使用 JavaScript Unicode 转义。
上一篇:前端的安全问题


下一篇:Web应用漏洞-NGINX各类请求头缺失对应配置