自闭合 HTML 标签的不安全扩展¶
ID: js/unsafe-html-expansion
Kind: problem
Security severity: 6.1
Severity: warning
Precision: very-high
Tags:
- correctness
- security
- external/cwe/cwe-079
- external/cwe/cwe-116
Query suites:
- javascript-code-scanning.qls
- javascript-security-extended.qls
- javascript-security-and-quality.qls
为 HTML 元字符清理不受信任的输入是防止跨站点脚本攻击的常用技术。但是,如果在浏览器将清理后的输入视为 HTML 之前对其进行进一步修改,即使是清理后的输入也可能很危险。看似无害的转换,将自闭合 HTML 标签从 <div attr="{sanitized}"/>
扩展到 <div attr="{sanitized}"></div>
,实际上可能会导致跨站点脚本漏洞。
建议¶
尽可能使用经过良好测试的清理库,并在将清理后的值视为 HTML 之前,避免对其进行进一步修改。
一个更安全的替代方案是设计应用程序,使其不需要清理,例如使用明确说明其将哪些值视为 HTML 的 HTML 模板。
示例¶
以下函数将自闭合 HTML 标签转换为一对打开/关闭标签。它对所有非 img
和非 area
标签执行此操作,方法是使用具有两个捕获组的正则表达式。第一个捕获组对应于标签的名称,第二个捕获组对应于标签的内容。
function expandSelfClosingTags(html) {
var rxhtmlTag = /<(?!img|area)(([a-z][^\w\/>]*)[^>]*)\/>/gi;
return html.replace(rxhtmlTag, "<$1></$2>"); // BAD
}
虽然通常都知道正则表达式不适合解析 HTML,但这种特定转换模式的变体长期以来被认为是安全的。
但是,该函数并不安全。例如,请考虑以下字符串
<div alt="
<x" title="/>
<img src=url404 onerror=alert(1)>"/>
当上述函数转换字符串时,它会变成一个字符串,当浏览器将其视为 HTML 时,会导致警报。
<div alt="
<x" title="></x" >
<img src=url404 onerror=alert(1)>"/>
参考资料¶
jQuery: jQuery 3.5.0 中的安全修复
OWASP: 基于 DOM 的 XSS 防御备忘单。
OWASP: XSS(跨站点脚本)防御备忘单。
OWASP 跨站点类型。
维基百科: 跨站点脚本。
常见弱点枚举: CWE-79。
常见弱点枚举: CWE-116。