欢迎光临
我们一直在努力

XSS 攻防全解:反射型、存储型、DOM 型实战演示

文章目录

    • 一、先建立正确心智:XSS 伤的是谁
    • 二、三类 XSS:一张表建立直觉
    • 三、反射型 XSS:实战演示思路
      • 1. 它长什么样
      • 2. 演示路径(请在靶场做)
      • 3. 位置比 payload 重要
      • 4. 反射型的修复直觉
    • 四、存储型 XSS:实战演示思路
      • 1. 它为什么更凶
      • 2. 演示路径(靶场)
      • 3. 富文本:存储型的重灾区
      • 4. 存储型修复直觉
    • 五、DOM 型 XSS:实战演示思路
      • 1. 为什么说“服务端可能是清白的”
      • 2. 演示路径(自建一小页即可)
      • 3. 现代前端里的变体
      • 4. DOM 型修复直觉
    • 六、串起来的一条“实战演示”主线(适合内训)
    • 七、测试方法论(比收藏 payload 重要)
      • 1. 找入口
      • 2. 探针优先
      • 3. 看上下文再构造
      • 4. 双浏览器 / 双账号
      • 5. 自动化辅助,人工收口
    • 八、防御全解:分层才像会打仗
      • 1. 输出编码(第一原则)
      • 2. 输入校验(辅助)
      • 3. 富文本清理
      • 4. Cookie:HttpOnly、Secure、SameSite
      • 5. CSP(Content Security Policy)
      • 6. 框架与危险 API 纪律
      • 7. 安全头与其它
    • 九、和 OWASP Top 10 的关系
    • 十、常见误区
    • 十一、收尾

XSS(Cross-Site Scripting,跨站脚本)听起来像某种高深的“跨站黑科技”,真落到业务里,多半是一句很土的话:

页面把用户可控的内容,当成了脚本执行了。

可能是搜索框把关键字原样写回 HTML;可能是评论区存了一段 <script>,谁打开谁中招;也可能是前端用 innerHTML 拼了个 URL 参数,压根没经过服务端。三种常见面孔——反射型、存储型、DOM 型——本质同一类病:不可信数据进了浏览器的“代码语境”。

另外说句实在话:现在 HttpOnly、框架自动转义、CSP 越来越普及,有人宣布 XSS 已死。然后每年还能在重要系统里看见评论区、富文本、运营配置后台、老 jQuery 页面中招。死的是“无脑 <script>alert(1)”,不是整个问题域。


一、先建立正确心智:XSS 伤的是谁

SQL 注入主要伤服务器和数据;XSS 主要伤正在用浏览器的人。

脚本跑在受害者浏览器里,能做的事情取决于页面所处的源(origin)和页面能力,常见包括:

  • 偷当前站可用的数据(若 Cookie 非 HttpOnly,可能读到会话 Cookie;HttpOnly 则改走其它路);
  • 以受害者身份发请求(改邮箱、转账、发帖),也就是挂着用户会话的 CSRF 式操作;
  • 钓鱼:在真域名下画假登录框;
  • 配合其它洞做跳板。

所以评估 XSS 时,别停在 alert(1)。alert 只是证明“我能执行脚本”。真正的问题是:在谁的浏览器里、以谁的身份、能碰到什么功能。


二、三类 XSS:一张表建立直觉

类型脚本从哪来典型触发测试时盯什么
反射型 当前请求参数被立刻写进页面 点开带毒链接 URL/表单参数是否进 HTML
存储型 先存进服务器,以后每次打开都带出来 看帖、看消息、看后台 存储内容再展示的路径
DOM 型 主要在前端 JS 里改 DOM 改 hash/参数即可 innerHTML、eval、危险 sink

一句话区分:

  • 反射:请求里来,响应里走,多半不进库;
  • 存储:进库(或进能持久的地方),别人也会中;
  • DOM:服务端可能完全干净,锅在前端。

三、反射型 XSS:实战演示思路

1. 它长什么样

最典型:搜索页。

你搜 hello,页面显示“您搜索的是:hello”。若后端或模板把关键字不经编码塞进 HTML,把关键字换成可执行的 HTML/JS,浏览器就会执行。

受害者通常需要打开攻击者构造好的链接(或被钓鱼点开)。所以反射型常和社工、短链、广告投放一起出现。

2. 演示路径(请在靶场做)

环境: DVWA 反射型关卡,或自己写一个“回显参数”的页面。

步骤大致是:

  • 找一个参数,它的值会出现在响应 HTML 里;
  • 先提交一个无害标记,例如 xss_probe_12345,确认它原样出现在哪里(标题、属性、正文、脚本块里位置不同,手法不同);
  • 根据位置尝试能否形成可执行上下文——例如是否进了标签体、是否进了属性、是否进了 JavaScript 字符串;
  • 用最简单的执行证明(教学上常用弹窗)证明脚本执行;
  • 再讨论:若 Cookie 无 HttpOnly 会怎样(演示到“能读到什么”为止,别对外打真实账号)。
  • 3. 位置比 payload 重要

    同样是“注入字符串”,落点不同难度差很多:

    • 落在 HTML 文本节点:常要形成标签;
    • 落在属性值:要考虑引号闭合、事件属性;
    • 落在已有 <script> 字符串里:要考虑引号与编码;
    • 落在 URL 属性:可能变成 javascript: 协议问题。

    老手第一件事不是砸字典,是看回显点源码上下文。Chrome F12 比一百条盲打有用。

    4. 反射型的修复直觉

    模板引擎默认转义;输出到 HTML 用对应编码;能用纯文本就别用“可解析 HTML”。 业务若必须允许链接,用白名单标签的清理库,别自己写正则“过滤 script”。


    四、存储型 XSS:实战演示思路

    1. 它为什么更凶

    脚本躺在服务器上(评论、文章、用户简介、工单回复、后台配置)。受害者只要正常浏览,就可能中招——不一定非要点奇怪链接。管理员一打开“用户反馈”,管理会话就可能交代。

    所以存储型在危害评级里通常高于同类反射型:影响面是“谁会看到这条数据”。

    2. 演示路径(靶场)

  • 找会保存并再展示的功能:留言板最经典;
  • 提交探针字符串,保存后打开详情页,看是否原样进 HTML;
  • 换成可执行证明,用另一个浏览器配置/另一个账号打开,确认“存储后触发”;
  • 观察触发角色:普通用户互看?还是仅管理员后台预览?角色决定危害。
  • 3. 富文本:存储型的重灾区

    产品经理常说:“评论要支持加粗和图片。” 于是上线富文本编辑器,服务端若只做半吊子过滤,攻击者就能塞事件属性、畸形标签、svg onload 之类。

    这里有个残酷事实:自己写 HTML 过滤器几乎必输。 用成熟的、默认安全的清理库(并保持更新),白名单标签与属性,去掉事件处理器和危险协议。

    4. 存储型修复直觉

    • 存可以存原文,出必须按上下文编码;或
    • 存之前就清理成安全子集;
    • 管理端预览也要走同一套安全输出,别“后台信任自己人”。

    五、DOM 型 XSS:实战演示思路

    1. 为什么说“服务端可能是清白的”

    DOM XSS 的数据流主要在浏览器里:

    源(source):location、hash、referrer、postMessage…
    ↓ 前端 JS 处理
    汇(sink):innerHTML、document.write、eval、$('…').html()…

    服务端返回的 HTML 可能完全固定;脚本执行是前端自己用不可信数据去喂了危险 API。

    传统只抓包看响应的测试,会漏掉 DOM XSS。要用浏览器调试,看参数进了哪段 JS。

    2. 演示路径(自建一小页即可)

    很多教程会写一个糟糕页面:从 location.hash 取字符串,赋给 innerHTML。你改 URL 的 # 后面内容,页面就会执行。

    练习时建议你亲自写坏再修好:

  • 先复现危险写法;
  • 改成 textContent 或明确创建文本节点;
  • 若必须插 HTML,用经过清理的结果,并考虑 CSP。
  • 3. 现代前端里的变体

    • 前端路由把 query 写进页面;
    • postMessage 没验 origin;
    • 从 localStorage 读出以前存的脏数据再 innerHTML;
    • 第三方小部件配置项进 DOM。

    SPA 流行后,DOM XSS 的占比其实上升了——只是名字不总叫“跨站”,而叫“前端漏洞”。

    4. DOM 型修复直觉

    危险 sink 清单贴在团队 Wiki:禁止对不可信数据用 innerHTML / document.write / 拼 on* 属性。 React 默认文本转义有帮助,但 dangerouslySetInnerHTML 就是明示危险;Vue 的 v-html 同理。用之前问:数据从哪来?


    六、串起来的一条“实战演示”主线(适合内训)

    如果你要做一场两小时内部演示,我建议别三类各打一遍字典,而是讲一个故事:

    场景: 一个带搜索、评论、前端高亮关键词的小站点。

  • 反射: 搜索关键词回显 → 证明反射型;
  • 存储: 评论保存恶意内容 → 另一账号打开帖子中招;
  • DOM: 前端用 URL 参数高亮关键词,却 innerHTML → 服务端已转义仍中招。
  • 同一业务三种洞,学员一下就懂“输出编码要按场景做,前端也是战场”。

    演示结束一定留 15 分钟讲修复提交:模板转义、评论清理、前端改 textContent、加一层 CSP。否则演示就是表演玩火。


    七、测试方法论(比收藏 payload 重要)

    1. 找入口

    所有用户可控且可能被展示的地方:参数、表单、上传文件名、头像 URL、回调地址、邮件模板、运营配置。 别忽略“只有管理员能看的数据”——那经常是存储型高危。

    2. 探针优先

    先用独一无二的字符串确认数据流,再谈执行。 乱砸 payload 会被 WAF 干扰,你也分不清是没回去还是被过滤。

    3. 看上下文再构造

    进 HTML、属性、JS、CSS、URL,编码方式不同。 “万能 payload”是幻觉;上下文才是地图。

    4. 双浏览器 / 双账号

    存储型必须验证“他人视角”。反射型验证“换个未登录/另一用户点链接”。

    5. 自动化辅助,人工收口

    爬虫式 XSS 扫描器能找简单反射;DOM 与业务型存储仍靠人。扫出来的东西要人工确认,减少把标签过滤误报当战果。


    八、防御全解:分层才像会打仗

    1. 输出编码(第一原则)

    数据离开信任边界、进入 HTML/属性/JS 时,做对应上下文的编码。 在现代框架里,优先用默认转义的模板绑定,少拼原始 HTML。

    2. 输入校验(辅助)

    长度、格式、白名单字符——能减少垃圾,不能当唯一防线。攻击者编码花样太多。

    3. 富文本清理

    成熟库 + 白名单;升级跟依赖 SLA 走。 允许的标签里不要留事件属性;URL 只允许 http(s)。

    4. Cookie:HttpOnly、Secure、SameSite

    HttpOnly 让 JS 读不到会话 Cookie,能挡一类偷票;不挡以用户身份发请求的那类攻击,所以还要配合 CSRF 防护与敏感操作二次确认。

    5. CSP(Content Security Policy)

    CSP 像给浏览器下“脚本纪律”:默认禁止乱七八糟的内联脚本与陌生域脚本时,XSS 成功率会断崖下降。 落地难在兼容:要先 Report-Only 观察,再 enforce;尽量配合非ce 降低绕过。别指望一天全站完美 CSP,但关键登录域值得先做。

    6. 框架与危险 API 纪律

    禁止清单比鼓励清单好使:Code Review 扫 dangerouslySetInnerHTML、v-html、innerHTML=。 发现一处,问数据源。

    7. 安全头与其它

    X-Content-Type-Options: nosniff 等减少浏览器猜类型带来的意外。 完整安全头方案可另开一篇;这里只强调:XSS 不是只靠一个头解决。


    九、和 OWASP Top 10 的关系

    XSS 在旧版 Top 10 里单列多年,2021 起更多并入注入/其它类别的讨论,但业务上它仍独立存在。 和 A01 越权常联动:先 XSS 管理员,再改配置;和 A07 认证失败也联动:伪造登录框收口令。 修 XSS 时顺手看敏感操作有没有二次验证,性价比很高。


    十、常见误区

    “我们过滤了 script 关键字。” 大小写、编码、标签变形、事件属性、SVG,正则防 XSS 历史记录不太光彩。

    “框架默认防 XSS,所以没事。” 直到有人用了危险 API,或把用户 HTML 当可信。

    “有 WAF。” WAF 挡一部分反射;存储与 DOM 经常绕开它的舒适区。

    “HttpOnly 了,XSS 没用。” 攻击者仍可以让浏览器自己去点“删除账号”“导出数据”。

    “内部系统不需要防 XSS。” 内部系统才常有高权限用户,存储型更值钱。


    十一、收尾

    反射型像钓鱼链接上的一次性炮弹; 存储型像埋在业务数据里的地雷; DOM 型像前端自己挖的坑,服务端查岗都可能查不到。

    攻的一方(授权测试)要会看上下文、会追数据流、会换角色验证; 防的一方要把输出编码、富文本纪律、危险 sink、CSP、Cookie 属性做成默认,而不是出了事再救火。

    今晚若只做一件事:打开你们站点一个“用户输入会显示出来”的页面,在测试环境提交一个独一无二的探针字符串,然后 View Source 看它落在谁家里——标签体、属性,还是进了某段前端模板。 认清落点之后,你对 XSS 的理解会比背十个弹窗字符串扎实得多。

    三类演示都走通以后,你会发现所谓“全解”其实不神秘: 数据在哪里变成了代码,就在哪里设防。


    赞(0)
    未经允许不得转载:171主机测评 » XSS 攻防全解:反射型、存储型、DOM 型实战演示
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址