XSS上下文
翻译
原文:https://portswigger.net/web-security/cross-site-scripting/contexts
- name: 翻译
desc: 原文:https://portswigger.net/web-security/cross-site-scripting/contexts
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# XSS上下文
在测试反射和存储型的 XSS 时,关键任务是识别 XSS 上下文:
- 攻击者可控数据在响应中出现的位置。
- 应用程序对该数据执行的 任何输入验证或其他处理。
根据这些细节,你可以选择一个或多个候选 XSS 有效负载,并测试它们是否有效。
笔记
我们构建了一个全面的XSS备忘单 (opens new window)来帮助你测试 Web 应用程序和过滤器。你可以按事件和标签进行筛选,并查看哪些向量需要用户交互。备忘单还包含AngularJS (opens new window)沙盒转义和许多其他部分,以帮助你进行 XSS 研究。
# 1位于HTML标签之间的XSS
当 XSS 上下文位于 HTML 标签之间的文本时,你需要引入一些新的 HTML 标签来触发 JavaScript 的执行。
执行 JavaScript 的一些有效方法是:
<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>
2
- 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/reflected/lab-html-context-nothing-encoded
bgColor: '#001350'
textColor: '#39d50c'
2
3
4
5
6
- 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
- name: 实验室-从业者
desc: XSS上下文-HTML标签间的反射型XSS-大多数标签和属性被阻止 >>
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/contexts/lab-html-context-with-most-tags-and-attributes-blocked
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
- name: 实验室-从业者
desc: XSS上下文-HTML标签间的反射型XSS-除了自定义标签外的所有标签都被阻止 >>
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/contexts/lab-html-context-with-all-standard-tags-blocked
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
- name: 实验室-专家
desc: XSS上下文-HTML标签间的反射型XSS-事件处理程序和href属性被阻止 >>
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/contexts/lab-event-handlers-and-href-attributes-blocked
bgColor: '#001350'
textColor: '#d112fe'
2
3
4
5
6
- name: 实验室-从业者
desc: XSS上下文-HTML标签间的反射型XSS-允许使用SVG标签 >>
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/contexts/lab-some-svg-markup-allowed
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 2位于HTML标签属性中的XSS
当 XSS 上下文进入 HTML 标签的属性值中时,可以尝试终止属性值、闭合原标签并引入新标签。例如:
"><script>alert(document.domain)</script>
在这种情况下,尖括号通常会被阻止或编码,因此你的输入无法脱离它所在的标签。但,如果可以终止原来的属性值,则可以引入一个新属性,来创建可执行脚本的上下文,例如事件处理程序。举例来说:
" autofocus onfocus=alert(document.domain) x="
上面的有效负载创建了一个onfocus
事件,当元素接收到焦点时,该事件将执行 JavaScript,并且还添加了autofocus
属性来尝试自动触发onfocus
事件,这样一来就无需任何用户交互。最后,它添加x="
以优雅地修复后方标记。
- name: 实验室-学徒
desc: XSS上下文-HTML属性中的反射型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/contexts/lab-attribute-angle-brackets-html-encoded
bgColor: '#001350'
textColor: '#39d50c'
2
3
4
5
6
有时,XSS 上下文是某一种 HTML 标签属性,该属性本身可以创建一个脚本上下文。在这里,你可以执行 JavaScript 而无需终止属性值。例如,如果 XSS 上下文位于锚点标签的href
属性中,则可以使用javascript
伪协议来执行脚本。例如:
<a href="javascript:alert(document.domain)">
- name: 实验室-学徒
desc: XSS上下文-锚点href属性中的存储型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/contexts/lab-href-attribute-double-quotes-html-encoded
bgColor: '#001350'
textColor: '#39d50c'
2
3
4
5
6
你可能会遇到这类网站——对尖括号进行编码,但允许你注入属性值。有时,载荷注入点会位于一些 不会自动触发事件的标签中,例如 canonical 标签,但这仍然可能被利用。在 Chrome 上,你可以使用 Access keys 和用户进行交互,从而利用此行为。Access keys 允许你提供 “引用特定元素的键盘快捷键”。accesskey
属性允许你定义一个字母,当与其他键(这些键因不同平台而异)组合按下时,将导致事件触发。在下一个实验中,你可以尝试使用 Access keys 来利用 canonical 标签。此外,你还可以使用 PortSwigger Research 发明的技术在隐藏的 input 字段中利用 XSS。 (opens new window)
(((译者加:canonical 标签又被叫作 “规范标签”,有关该标签的详细信息可参阅这篇文章 (opens new window))))
- name: 实验室-从业者
desc: XSS上下文-link规范标签中的反射型XSS >>
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/contexts/lab-canonical-link-tag
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 3位于JavaScript中的XSS
当 XSS 上下文位于响应中的一些现有 JavaScript 中时,可能会出现各种各样的情况,若想成功执行漏洞利用,则需要使用不同的技术。
# 3.1终止现有脚本
在最简单的情况下,可以轻松地关闭包含现有 JavaScript 脚本的标签,并引入一些新的 HTML 标签来触发恶意 JavaScript 的执行。例如,如果 XSS 上下文是这样的:
<script>
...
var input = 'controllable data here';
...
</script>
2
3
4
5
那么,你可以使用以下有效负载来突破现有的 JavaScript 并执行你自己的 JavaScript:
</script><img src=1 onerror=alert(document.domain)>
这样做的原因是——浏览器首先执行 HTML 解析来识别页面元素,包括脚本块,然后才执行 JavaScript 解析来理解和执行嵌入式脚本。上述有效负载使原始脚本中断,并留有未终止的字符串文本。但这并不妨碍后续脚本以正常方式解析和执行。
- name: 实验室-从业者
desc: XSS上下文-JavaScript字符串中的反射型XSS-单引号和反斜杠转义 >>
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/contexts/lab-javascript-string-single-quote-backslash-escaped
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 3.2脱离JavaScript字符串
当 XSS 上下文位于带引号的字符串文本中时,通常可以脱离字符串并直接执行 JavaScript。但你必须根据 XSS 上下文修复脚本,因为那里的任何语法错误都会阻止整个脚本的执行。
中断字符串文本的一些有用方法是:
'-alert(document.domain)-'
';alert(document.domain)//
2
- name: 实验室-学徒
desc: XSS上下文-JavaScript字符串中的反射型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/contexts/lab-javascript-string-angle-brackets-html-encoded
bgColor: '#001350'
textColor: '#39d50c'
2
3
4
5
6
一些应用程序试图通过 反斜杠 来转义任何单引号字符,以防止用户输入中断 JavaScript 字符串。字符前面的反斜杠告诉 JavaScript 解析器应按字面意思解释该字符,而不是作为特殊字符(如字符串结束符)。在这种情况下,应用程序经常会犯一个错误——未转义反斜杠字符本身。这意味着攻击者可以使用自己的反斜杠字符,来抵消应用程序所添加的反斜杠。
例如,假设输入:
';alert(document.domain)//
被转换为:
\';alert(document.domain)//
你现在可以使用替代有效负载:
\';alert(document.domain)//
这次被转换为:
\\';alert(document.domain)//
在这里,第一个反斜杠代表着第二个反斜杠是按字面解释的,而不是作为特殊字符。这意味着引号现在被解释为字符串结束符,因此攻击成功。
- name: 实验室-从业者
desc: XSS上下文-JavaScript字符串中的反射型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/contexts/lab-javascript-string-angle-brackets-double-quotes-encoded-single-quotes-escaped
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
一些网站限制了允许使用的字符,这使 XSS 变得更加困难。这可以是网站级别的防护,也可以通过部署 WAF 来阻止你的请求到达网站。在这种情况下,你需要尝试使用其他方法,来绕过安全措施并调用函数。执行此操作的一种方法是将throw
语句与异常处理程序一起使用,这能够使你在不使用括号的情况下将参数传递给函数。以下代码将alert()
函数分配给全局异常处理程序,throw
语句将1
传递给异常处理程序(在本例中为alert
)。最终结果是调用alert()
函数,并以数字1
作为参数。
onerror=alert;throw 1
有多种方法可以用来实现此技术,从而调用无括号函数 (opens new window)。
在下个实验中,将演示一个过滤某些特定字符的网站。你必须使用与上述类似的技术才能解决它。
- name: 实验室-专家
desc: XSS上下文-JavaScript URL中的反射型XSS-某些字符被阻止 >>
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/contexts/lab-javascript-url-some-characters-blocked
bgColor: '#001350'
textColor: '#d112fe'
2
3
4
5
6
# 3.3利用 HTML 编码
当 XSS 上下文位于带引号的标签属性(如事件处理程序)中的一些现有 JavaScript 时,可以使用 HTML 编码来应对某些输入过滤器。
当浏览器解析出响应中的 HTML 标签和属性时,它在进一步处理标签属性值之前,将会对其执行 HTML 解码。如果服务器端应用程序阻止或清理了 XSS 漏洞所需的某些字符,则可以尝试对这些字符进行 HTML 编码来绕过输入验证。
例如,如果 XSS 上下文是这样的:
<a href="#" onclick="... var input='controllable data here'; ...">
同时,应用程序阻止或转义单引号字符,则你可以使用以下有效负载来脱离 JavaScript 字符串并执行你自己的脚本:
'-alert(document.domain)-'
'
序列是一个 HTML 实体,用于表示撇号或单引号。由于浏览器在解析 JavaScript 之前会对onclick
属性的值进行 HTML 解码,因此实体被解码为引号,引号成为字符串分隔符,因此攻击成功。
- name: 实验室-从业者
desc: XSS上下文-onclick属性中的存储型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/contexts/lab-onclick-event-angle-brackets-double-quotes-html-encoded-single-quotes-backslash-escaped
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 3.4JavaScript模板字面量中的XSS
JavaScript 模板字面量是允许嵌入 JavaScript 表达式的字符串文本。嵌入的表达式被计算后,通常会连接到周围的文本中。模板字面量封装在反引号中,而不是普通引号中,嵌入式表达式使用${...}
作为语法标识。
例如,以下脚本将打印包含用户展示名称的欢迎消息:
document.getElementById('message').innerText = `Welcome, ${user.displayName}.`;
当 XSS 上下文进入 JavaScript 模板字面量时,不需要终止文本。相反,你只需要使用${...}
语法来嵌入一个 JavaScript 表达式,该表达式将在文本处理时被执行。例如,如果 XSS 上下文是这样的:
<script>
...
var input = `controllable data here`;
...
</script>
2
3
4
5
然后,你可以使用以下有效负载来执行 JavaScript,而无需终止模板字面量:
${alert(document.domain)}
- name: 实验室-从业者
desc: XSS上下文-模板字面量中的反射型XSS-尖括号单引号双引号反斜杠和反引号Unicode转义 >>
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/contexts/lab-javascript-template-literal-angle-brackets-single-double-quotes-backslash-backticks-escaped
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 4通过客户端模板注入实现XSS
一些网站使用客户端模板框架(如 AngularJS)来动态渲染网页。如果他们以不安全的方式,将用户输入嵌入到这些模板中,则攻击者也许能够注入自己的恶意模板表达式,从而发起 XSS 攻击。