JavaScript无法单靠函数自动防御XSS,必须区分上下文、严格转义、禁用危险API:innerHTML/outerHTML、document.write、eval、setTimeout/setInterval传字符串、location跳转含javascript:、new Function均可能触发XSS。
JavaScript 中无法靠单个函数“自动”防御 XSS,关键在于区分上下文、严格转义、避免危险 API。
以下行为只要输入未过滤,就可能执行恶意脚本:
innerHTML、outerHTML 赋值含用户数据的字符串document.write() 或 document.writeln() 写入未处理内容eval()、setTimeout(string, ...)、setInterval(string, ...) 执行拼接的字符串location.href、location.assign() 跳转到拼接的 URL(尤其含 javascript: 伪协议)new Function(...) 动态构造函数HTML 内容、HTML 属性、URL、JS 字符串,各自有独立的转义规则。混用等于白做。
div.innerHTML = ...):必须对 、>、&、"、' 做 HTML 实体编码,推荐用 DOMPurify.sanitize()(而非仅转义)
el.setAttribute('title', userText)):需先做 HTML 实体编码,且属性值必须用引号包裹(单/双皆可),避免闭合失败a.href = '/search?q=' + userInput):必须用 encodeURIComponent(),不能用 encodeURI()(后者不编码 /、? 等)console.log('${userInput}')):需用 JSON 序列化——JSON.stringify(userInput),它会正确处理引号、反斜杠和控制字符开发者常误以为做了防护,实际仍可绕过:
标签:攻击者可用 或
javascript::可绕过为 javascript:、JaVaScRiPt:、换行或空格分隔in
nerHTML 插入,服务端转义可能被二次解释,应由前端在对应上下文做最终转义textContent 就万事大吉:它确实防 XSS,但若后续又取 textContent 拼进 innerHTML,风险重现不依赖框架时,优先采用“上下文感知 + 白名单净化”:
DOMPurify.sanitize(htmlString, {ALLOWED_TAGS: ['b','i','p'], ALLOWED_ATTR: ['class']}) —— 不要自己写过滤逻辑textContent 或 innerText(注意两者差异:innerText 受 CSS 影响,textContent 更可靠)JSON.parse() 消费,避免解析 HTML 片段template + content.cloneNode(true) 或 document.createElement() 构建节点最易被忽略的是事件处理器和 URL 构造:哪怕用了 DOMPurify,如果把用户输入直接塞进 onclick 属性或 location.href,依然会触发 XSS。上下文永远比库更重要。