用户输入的javascript:伪协议怎么防不住XSS?
在React项目里处理用户提交的留言内容时,发现如果用户输入类似javascript:alert(1)这样的内容,直接渲染后居然真的会执行脚本。虽然用了DOMPurify清理和转义特殊字符,但测试输入点击后点击链接还是会触发弹窗…
function MessageDisplay({ userContent }) {
// 使用DOMPurified清理内容
const sanitized = DOMPurify.sanitize(userContent, {
ALLOWED_TAGS: ['a', 'br', 'strong']
});
return (
<div
dangerouslySetInnerHTML={{ __html: sanitized }}
/>
);
}
尝试过设置Content-Security-Policy头和属性转义,但javascript:伪协议似乎能绕过过滤。这种情况下该怎么彻底阻断伪协议执行?单纯替换掉javascript:字符串会不会太粗暴?
关键点有两个:
1. **DOMPurify 要启用 KEEP_CONTENTPOLICY**
默认不会过滤伪协议,得手动加配置:
2. **强制移除 javascript: 协议**
即使启用了 KEEP_CONTENTPOLICY,默认也不会自动过滤 javascript:,你得加个自定义钩子:
这样处理完之后,javascript:alert(1) 的链接就不会保留 href 属性了,点击也不会执行。
当然,最安全的做法还是:**尽量避免使用 dangerouslySetInnerHTML**,改成文本渲染,富文本部分用白名单控制。如果只是展示留言,直接用 React 组件结构渲染用户内容会更安全。
XSS 真的防不胜防,特别是带伪协议的链接,光靠 sanitizer 不够,前端加一层清理钩子是必须的。单纯替换 javascript: 也不算粗暴,但容易漏掉变形绕过的 payload,还是结合 sanitizer 钩子更稳妥。