存储型XSS
翻译
原文:https://portswigger.net/web-security/cross-site-scripting/stored
- name: 翻译
desc: 原文:https://portswigger.net/web-security/cross-site-scripting/stored
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# 存储型XSS
在本节中,我们将解释存储型跨站脚本,描述存储型 XSS 攻击的影响,并详细说明如何发现存储型 XSS 漏洞。
# 1什么是存储型XSS?
当应用程序从不受信任的源接收数据,并以不安全的方式将这些数据包含在其之后的 HTTP 响应中时,就会出现存储型跨站点脚本(也称为二阶或持久性 XSS)。
假设一个网站允许用户对博客文章提交评论,这些评论将会显示给其他用户。用户使用如下所示的 HTTP 请求提交评论:
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Length: 100
postId=3&comment=This+post+was+extremely+helpful.&name=Carlos+Montoya&email=carlos%40normal-user.net
2
3
4
5
提交此评论后,访问博客文章的任何用户,都将会在应用程序的响应中收到以下内容:
<p>This post was extremely helpful.</p>
假设应用程序不对数据执行任何其他处理,攻击者可以提交如下恶意评论:
<script>/* Bad stuff here... */</script>
在攻击者的请求中,此评论将被 URL 编码为:
comment=%3Cscript%3E%2F*%2BBad%2Bstuff%2Bhere...%2B*%2F%3C%2Fscript%3E
访问博客文章的任何用户,现在都将会在应用程序的响应中收到以下内容:
<p><script>/* Bad stuff here... */</script></p>
然后,攻击者提供的脚本将在受害用户的浏览器中执行,在他们与应用程序的会话上下文中。
- name: 实验室-学徒
desc: 存储型XSS-未编码的HTML上下文 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/cross-site-scripting/stored/lab-html-context-nothing-encoded
bgColor: '#001350'
textColor: '#39d50c'
2
3
4
5
6
# 2存储型 XSS 攻击的影响
在受害者的浏览器中,如果攻击者可以控制所执行的脚本,则他们通常可以完全危及该用户的安全。攻击者可以执行适用于反射型XSS (opens new window)漏洞的任何相同操作。
在可利用性方面,反射型和存储型 XSS 之间的主要区别在于,存储型 XSS 漏洞能够使攻击载荷自包含于应用程序本身。攻击者不需要找到一种外部方法,来诱使其他用户发出包含其载荷的特定请求。相反,攻击者将他们的载荷置于应用程序本身当中,并简单地等待用户遇到它。
存储型跨站点脚本攻击的自包含性质,在 XSS 漏洞仅影响当前登录到应用程序的用户的情况下尤其重要。如果 XSS 被反射,那么攻击必须是偶然的定时:在未登录时被诱导发出攻击者请求的用户不会受到损害。相反,如果存储了 XSS,则保证用户在遇到漏洞时登录。
在 XSS 漏洞仅影响 应用程序当前已登录用户 的情况下,存储型 XSS 攻击的自包含特性尤其重要。如果 XSS 被反射,那么攻击一定是偶然发生的:用户在未登录时被诱导发出攻击者的请求,将不会受到危害。相反,如果使用存储型 XSS,则可以保证用户在遇到漏洞时处于登录状态。
# 3不同上下文中的存储型XSS
存储型 XSS 有许多不同的种类。在应用程序的响应中,存储数据的位置决定了利用该漏洞所需的有效负载类型,并且还可能影响漏洞的危害程度。
此外,如果应用程序在存储数据之前 或 在将存储的数据合并到响应中时,对数据执行任何验证或其他处理,这通常会影响所需的 XSS 有效负载类型。
# 4如何发现和测试存储型 XSS 漏洞
绝大多数存储型跨站脚本漏洞,都可以使用 Burp Suite 的Web漏洞扫描程序 (opens new window)快速而可靠地找到。
手动测试存储型 XSS 漏洞可能具有挑战性。你需要测试所有相关的 “入口点”,攻击者控制的数据可以通过这些入口点进入应用程序的处理,以及这些数据可能出现在应用程序响应中的所有 “出口点”。
进入应用程序处理的入口点包括:
- URL 查询字符串和消息正文中的参数或其他数据。
- URL 文件路径。
- 与反射型 XSS 有关的 HTTP 请求标头可能无法利用。
- 任何带外路由,攻击者可以通过这些路由将数据传送到应用程序中。存在的路由完全取决于应用程序所实现的功能:Web 邮件应用程序将处理电子邮件中接收到的数据; 显示 Twitter 摘要的应用程序可能会处理第三方推文中包含的数据; 而新闻聚合器将包括来自其他网站的数据。
存储型 XSS 攻击的出口点是——在任何情况下,返回给任何类型的应用程序用户 的所有可能的 HTTP 响应。
测试存储型 XSS 漏洞的第一步是——定位入口点和出口点之间的联系,由此处提交到入口点的数据 将会从出口点发出。这可能具有挑战性:
- 原则上,提交给任何入口点的数据,可以从任何出口点发出。例如,用户提供的展示名称,可能出现在 仅对某些应用程序用户可见的模糊审计日志中。
- 通常,由于在应用程序中执行了其他操作,导致程序当前存储的数据很容易被覆盖。例如,搜索功能可能会显示 “最近搜索” 的列表,当用户执行其他搜索时,这些搜索项会被迅速替换。
要想全面识别入口点和出口点之间的联系,需要分别测试每个排列方式,将特定值提交到入口点,直接导航到出口点,并确定该值是否出现在那里。但是,这种方法在具有多个页面的应用程序中并不实用。
相反,更现实的方法是系统地处理数据入口点,将特定值提交到每个入口点,并监视应用程序的响应 以检测所提交值的出现情况。可以特别注意相关的应用程序功能,例如博客文章的评论。在响应中观察到提交的值时,你需要确定数据是否确实存储在不同的请求中,而不是简单地反映在即时响应中。
当你在应用程序的处理过程中,确定了入口点和出口点之间的联系时,需要专门测试每个联系点,以检测是否存在存储型 XSS 漏洞。这需要确定在响应中存储数据的回显上下文,并测试适用于该上下文的候选 XSS 有效载荷。在这一点上,测试方法与查找反射型 XSS 漏洞大致相同。