我的JavaScript防XSS过滤代码是否存在绕过风险?如何修复?
你的当前过滤逻辑存在多个可被绕过的漏洞,具体场景和修复方案如下:
可绕过的攻击场景
- HTML实体/Unicode编码绕过:你只检查了原始的
<、>字符,但攻击者可以用实体编码(比如<对应<,>对应>)或者Unicode转义输入危险内容。例如输入<img src=x onerror=alert(1)>,你的过滤会因为没检测到<、>而放行,当innerHTML解析时,浏览器会自动把实体转成真实标签,触发XSS。 - 非script标签的恶意事件:XSS不一定需要
<script>标签,你的过滤只针对script字符串,完全没限制其他危险标签和事件。比如输入img src=x onerror=alert(1),这段内容里没有<、>、script,会通过过滤,innerHTML设置后会生成完整的<img>标签,加载失败时执行恶意代码。同理,div onmouseover=alert(1)、a href=javascript:alert(1)这类内容都能轻松绕过。 - 替换逻辑的潜在问题:你只做了一次
script字符串替换,不过当前前置检查已经拦截了包含script的内容,这个场景暂时不生效,但如果后续修改检查逻辑(比如移除前置判断),攻击者可以输入sscriptcript,替换后会变成script,从而触发XSS。
修复方案
- 用textContent/innerText替代innerHTML(推荐):这是最彻底的解决办法,
textContent会把所有内容当作纯文本渲染,不会解析任何HTML标签,从根源上避免XSS。修改后的代码如下:const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get('code'); const desc = urlParams.get('desc'); const codeEl = document.getElementById("txt-code"); if (code) { codeEl.textContent = code; } const descArea = document.getElementById("desc-area"); if (!desc || desc === '') { descArea.style.display = "none"; } else { const descEl = document.getElementById("txt-desc"); descEl.textContent = desc; } - 如果必须用innerHTML,做完整HTML实体编码:把所有特殊字符转成HTML实体,确保浏览器不会将其解析为标签。可以写一个简单的编码函数:
function htmlEncode(str) { return str.replace(/[&<>"']/g, char => { const entities = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return entities[char]; }); } // 使用示例 codeEl.innerHTML = htmlEncode(code); - 不要自己写过滤规则:手动过滤很容易遗漏各种攻击场景,建议使用专门的HTML净化库处理需要保留HTML的场景,确保只允许安全的标签和属性。
内容的提问来源于stack exchange,提问作者Humble
相关产品推荐
相关产品推荐

