前端如何安全处理URL参数防止XSS攻击?

欧阳司翰 阅读 4

我在做一个单页应用,需要从URL的查询参数里读取用户ID然后显示在页面上。之前直接用了new URLSearchParams(window.location.search).get('id')拿到值就插进DOM,结果被安全扫描工具报了XSS风险。

我试过用DOMPurify清洗,但不确定是不是过度防护了。有没有更轻量又靠谱的方式?比如只对特殊字符转义?下面是我现在的写法:

const userId = new URLSearchParams(window.location.search).get('id');
document.getElementById('user-name').textContent = userId;

这样用 textContent 应该没问题吧?还是说连读取阶段就要过滤?有点懵。

我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
FSD-纳利
这个问题其实涉及到两个关键点:1)从URL取值的环节 2)把值插入DOM的环节。我们分开来说。

首先你现在的写法其实已经比innerHTML安全很多了,textContent确实会自动转义HTML标签,这是它的天然优势。但安全扫描工具报XSS也不是完全没道理,因为如果id参数包含恶意脚本,比如 user1,虽然不会执行脚本,但会显示原样文本,体验很糟糕。

更安全的做法是分两步处理:

1. 取值时做基础过滤,确保是预期格式。比如用户ID通常只允许字母数字和特定符号:
function getSafeUserId() {
const rawId = new URLSearchParams(window.location.search).get('id');
// 只保留字母、数字、下划线和短横线,其他都过滤掉
return rawId ? rawId.replace(/[^w-]/g, '') : '';
}


2. 显示时如果确实需要显示原始输入(比如要保留用户输入的符号),可以用textContent配合额外的转义:
const userId = getSafeUserId();
const displayElement = document.getElementById('user-name');
displayElement.textContent = userId;

// 如果必须显示特殊字符但又担心XSS,可以这样双重保障
// displayElement.textContent = escapeHtml(userId);

// 简单的HTML转义函数
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/ .replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}


为什么这么处理:
- 正则过滤保证了输入内容在源头就是干净的
- textContent本身已经能防御HTML注入
- 额外的escapeHtml是给需要显示特殊字符的场景上的保险

需要注意:如果用户ID要用来做数据库查询之类的后端操作,前端过滤不能替代后端验证,必须两边都做校验。前端防护只是为了用户体验,后端才是真正的安全防线。

DOMPurify确实有点重,对于简单的文本显示场景没必要。除非你要处理富文本内容,否则用上面这种轻量级方案就够了。
点赞
2026-03-07 19:06