URL参数过滤时如何防止XSS攻击绕过?

夏侯艳艳 阅读 58

我在做用户分享链接功能时发现,用户输入的URL参数如果包含alert(1)会被正确拦截,但换成大写或者加注释就能绕过了,该怎么改进过滤逻辑呢?

尝试过用正则/<script>/i匹配标签,但发现这样:


// 用户输入的恶意参数
const userInput = "?src=//example.com?callback=alert(1)";

// 当前过滤函数
function sanitizeParam(param) {
  return param.replace(/<script>/gi, '');
}

这样处理后参数依然能执行脚本,是不是过滤策略太简单了?有没有更可靠的URL参数净化方案?

我来解答 赞 20 收藏
二维码
手机扫码查看
2 条解答
司马静依
你这个过滤方式确实太简单了,只处理 <script> 标签根本防不住 XSS,特别是 URL 参数这种上下文里,攻击手法太多了。试试这个方法:别想着靠正则把所有恶意内容删掉,根本拦不全,大小写、编码、注释、js 伪协议都能绕过。

正确的做法是:对 URL 参数里的值做严格白名单校验 + 转义输出。

比如用户分享链接的参数,假设是 callback 或 src 这种,你应该:

1. 明确允许的域名白名单
2. 用 URL 解析函数拆解输入,检查协议、host 是否在白名单内
3. 如果是纯字符串参数(比如用户名),只允许字母数字下划线

这里有个实际可用的 sanitize 函数示例:

function sanitizeUrlParam(paramValue) {
try {
// 尝试当URL处理
const url = new URL(paramValue, 'https://default.com');
const allowedHosts = ['example.com', 'trusted-site.com'];

if (!allowedHosts.includes(url.hostname)) {
return ''; // 不在白名单就清空
}

if (url.protocol !== 'https:' && url.protocol !== 'http:') {
return ''; // 只允许 http/https
}

return url.toString();
} catch (e) {
// 不是合法URL,当作普通字符串处理
// 只允许安全字符
return paramValue.replace(/[^a-zA-Z0-9._-]/g, '');
}
}


另外,在前端展示或拼接 URL 的时候,一定要用 encodeURIComponent 包一层再放进去。

记住一点:输入过滤不可靠,输出转义 + 上下文隔离才是王道。如果只是分享链接,建议后端也加一层校验,别全靠前端拦。
点赞 1
2026-02-11 22:19
广利
广利 Lv1
你这过滤方式确实太简单了。script标签只是XSS的一种载体,用正则替换根本防不住各种变形的攻击。URL参数里能触发XSS的地方多了去了,比如location.href、document.write这种反射操作。

防XSS的核心是「哪里输出,哪里转义」,不是靠过滤关键字。比如你在前端展示用户输入的URL参数时,应该对输出位置做处理:

1. 如果是放在HTML里,用innerText或者textContent
2. 如果是放在属性里,用encodeURIComponent
3. 如果是放在script标签里,用JSON.stringify

但你这里是要过滤URL参数,建议用白名单校验 + 编码的方式处理,比如:

function sanitizeParam(param) {
// 白名单允许的字符(字母数字和常见符号)
const safeChars = /^[a-zA-Z0-9-._~!$&'()*+,;=:@/?]*$/;

if (!safeChars.test(param)) {
// 不符合规则的直接拒绝
return '';
}

// 编码输出
return encodeURIComponent(param);
}


但这也不是万能的,因为有些场景需要保留特殊字符。所以更推荐你在前端展示用户输入的地方,做输出转义而不是输入过滤。

如果非得用过滤,可以试试用DOMPurify这个库,它是专门处理XSS的,比自己写正则靠谱多了:

import DOMPurify from 'dompurify';

function sanitizeParam(param) {
return DOMPurify.sanitize(param);
}


总之,XSS这玩意儿靠过滤关键字是防不住的,必须用成熟方案 + 输出转义一起上。别指望一个正则就能解决问题,不然永远在补洞。
点赞 3
2026-02-07 05:00