javascript中如何安全地处理xss【教程】

10次阅读

javaScript无法单靠函数自动防御xss,必须区分上下文、严格转义、禁用危险API:innerhtml/outerHTML、document.write、eval、setTimeout/setInterval传字符串location跳转含javascript:、new function均可能触发XSS。

javascript中如何安全地处理xss【教程】

JavaScript 中无法靠单个函数“自动”防御 XSS,关键在于区分上下文、严格转义、避免危险 API。

哪些操作会直接触发 XSS

以下行为只要输入未过滤,就可能执行恶意脚本:

  • innerHTMLouterHTML 赋值含用户数据的字符串
  • document.write()document.writeln() 写入未处理内容
  • eval()setTimeout(String, ...)setInterval(string, ...) 执行拼接的字符串
  • location.hreflocation.assign() 跳转到拼接的 URL(尤其含 javascript: 伪协议)
  • new Function(...) 动态构造函数

不同上下文要用不同的转义方式

HTML 内容、HTML 属性、URL、js 字符串,各自有独立的转义规则。混用等于白做。

  • 插入 HTML 内容(如 div.innerHTML = ...):必须对 >&"' 做 HTML 实体编码,推荐用 DOMPurify.sanitize()(而非仅转义)
  • 写入 HTML 属性(如 el.setAttribute('title', userText)):需先做 HTML 实体编码,且属性值必须用引号包裹(单/双皆可),避免闭合失败
  • 拼入 URL(如 a.href = '/search?q=' + userInput):必须用 encodeURIComponent(),不能用 encodeURI()(后者不编码 /? 等)
  • 嵌入 JS 字符串(如 console.log('${userInput}')):需用 json 序列化——JSON.stringify(userInput),它会正确处理引号、反斜杠和控制字符

哪些“看似安全”的做法其实很危险

开发者常误以为做了防护,实际仍可绕过:

立即学习Java免费学习笔记(深入)”;

  • 只过滤 标签:攻击者可用 javascript中如何安全地处理xss【教程】
  • 用正则替换 javascript::可绕过为 javascript:JaVaScRiPt:、换行或空格分隔
  • 服务端转义后前端再拼接:若前端又用 innerHTML 插入,服务端转义可能被二次解释,应由前端在对应上下文做最终转义
  • 信任 textContent 就万事大吉:它确实防 XSS,但若后续又取 textContent 拼进 innerHTML,风险重现

推荐的最小可行防护组合

不依赖框架时,优先采用“上下文感知 + 白名单净化”:

  • 所有动态插入 HTML 的场景,用 DOMPurify.sanitize(htmlString, {ALLOWED_TAGS: ['b','i','p'], ALLOWED_ATTR: ['class']}) —— 不要自己写过滤逻辑
  • 纯文本渲染一律用 textContentinnerText(注意两者差异:innerTextcss 影响,textContent 更可靠)
  • 服务端返回结构化数据(如 JSON),前端用 JSON.parse() 消费,避免解析 HTML 片段
  • 模板中避免拼接,改用原生 template + content.clonenode(true)document.createElement() 构建节点

最易被忽略的是事件处理器和 URL 构造:哪怕用了 DOMPurify,如果把用户输入直接塞进 onclick 属性或 location.href,依然会触发 XSS。上下文永远比库更重要。

text=ZqhQzanResources