URL参数过滤时如何防止XSS攻击绕过?
我在做用户分享链接功能时发现,用户输入的URL参数如果包含alert(1)会被正确拦截,但换成大写或者加注释就能绕过了,该怎么改进过滤逻辑呢?
尝试过用正则/<script>/i匹配标签,但发现这样:
// 用户输入的恶意参数
const userInput = "?src=//example.com?callback=alert(1)";
// 当前过滤函数
function sanitizeParam(param) {
return param.replace(/<script>/gi, '');
}
这样处理后参数依然能执行脚本,是不是过滤策略太简单了?有没有更可靠的URL参数净化方案?
<script>标签根本防不住 XSS,特别是 URL 参数这种上下文里,攻击手法太多了。试试这个方法:别想着靠正则把所有恶意内容删掉,根本拦不全,大小写、编码、注释、js 伪协议都能绕过。正确的做法是:对 URL 参数里的值做严格白名单校验 + 转义输出。
比如用户分享链接的参数,假设是 callback 或 src 这种,你应该:
1. 明确允许的域名白名单
2. 用 URL 解析函数拆解输入,检查协议、host 是否在白名单内
3. 如果是纯字符串参数(比如用户名),只允许字母数字下划线
这里有个实际可用的 sanitize 函数示例:
另外,在前端展示或拼接 URL 的时候,一定要用
encodeURIComponent包一层再放进去。记住一点:输入过滤不可靠,输出转义 + 上下文隔离才是王道。如果只是分享链接,建议后端也加一层校验,别全靠前端拦。
防XSS的核心是「哪里输出,哪里转义」,不是靠过滤关键字。比如你在前端展示用户输入的URL参数时,应该对输出位置做处理:
1. 如果是放在HTML里,用innerText或者textContent
2. 如果是放在属性里,用encodeURIComponent
3. 如果是放在script标签里,用JSON.stringify
但你这里是要过滤URL参数,建议用白名单校验 + 编码的方式处理,比如:
但这也不是万能的,因为有些场景需要保留特殊字符。所以更推荐你在前端展示用户输入的地方,做输出转义而不是输入过滤。
如果非得用过滤,可以试试用DOMPurify这个库,它是专门处理XSS的,比自己写正则靠谱多了:
总之,XSS这玩意儿靠过滤关键字是防不住的,必须用成熟方案 + 输出转义一起上。别指望一个正则就能解决问题,不然永远在补洞。