VYPR
Moderate severityNVD Advisory· Published Apr 21, 2022· Updated Aug 3, 2024

CVE-2022-28367

CVE-2022-28367

Description

OWASP AntiSamy before 1.6.6 allows XSS via HTML tag smuggling on STYLE content with crafted input. The output serializer does not properly encode the supposed Cascading Style Sheets (CSS) content.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

OWASP AntiSamy before 1.6.6 fails to encode CSS content, enabling XSS via HTML tag smuggling in elements.

Vulnerability

OWASP AntiSamy before version 1.6.6 contains a cross-site scripting (XSS) vulnerability in the processing of CSS content within ` tags. The library's output serializer does not properly encode the CSS content, allowing an attacker to smuggle HTML tags or malicious JavaScript inside CSS that will be rendered by the browser. The root cause lies in the processStyleTag method of the CssHandler, which prior to the fix only processed the first child node of a ` element and did not properly concatenate or encode multiple child nodes [1][2]. Versions prior to 1.6.6 are affected; a partial fix was released in 1.6.6, but the issue is fully resolved in 1.6.7 [4].

Exploitation

An attacker can exploit this vulnerability by providing crafted HTML input containing a ` tag with CSS that includes HTML fragments or script payloads. The attacker does not require authentication if the application accepts untrusted HTML (e.g., user comments, profiles). The input triggers the vulnerable code path in AntiSamy's scanner, which fails to properly encode the CSS content, allowing the injected HTML tags to pass through the sanitization filter. When a victim's browser renders the sanitized output, the smuggled HTML or JavaScript executes [1][2]. The commit diff shows that before the fix, only the first child node of the ` element was scanned, and after cleaning, only that node was updated; other child nodes were left in place, enabling tag smuggling [2].

Impact

Successful exploitation allows an attacker to inject arbitrary HTML and JavaScript into the context of the application's domain, leading to cross-site scripting (XSS). The attacker can steal cookies, session tokens, or perform actions on behalf of the victim user, potentially compromising the confidentiality and integrity of user data and the application's security [4]. The impact is moderate to high depending on the application's trust model and the sensitivity of data handled.

Mitigation

Users should upgrade to OWASP AntiSamy version 1.6.7 or later, which fully resolves the vulnerability. Version 1.6.6 contained a partial fix but was insufficient; the complete fix is in 1.6.7 [4]. For versions before 1.6.6, immediate upgrade is recommended. As a workaround, applications can disable the processing of CSS content in `` tags if not required, or apply additional output encoding. This CVE is not currently listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.owasp.antisamy:antisamyMaven
< 1.6.61.6.6

Affected products

3

Patches

1
0199e7e194db

Support multiple children handling on style tags

https://github.com/nahsra/antisamySebastián PassaroMar 27, 2022via ghsa
3 files changed · +35 9
  • src/main/java/org/owasp/validator/html/scan/AntiSamyDOMScanner.java+20 8 modified
    @@ -407,10 +407,17 @@ private boolean processStyleTag(Element ele, Node parentNode) {
             CssScanner styleScanner = new CssScanner(policy, messages, policy.isEmbedStyleSheets());
     
             try {
    -            Node firstChild = ele.getFirstChild();
    -            if (firstChild != null) {
    +            if (ele.getChildNodes().getLength() > 0) {
    +                String toScan = "";
    +
    +                for (int i = 0; i < ele.getChildNodes().getLength(); i++) {
    +                    Node childNode = ele.getChildNodes().item(i);
    +                    if (!toScan.isEmpty()){
    +                        toScan += "\n";
    +                    }
    +                    toScan += childNode.getTextContent();
    +                }
     
    -                String toScan = firstChild.getNodeValue();
                     CleanResults cr = styleScanner.scanStyleSheet(toScan, policy.getMaxInputSize());
                     errorMessages.addAll(cr.getErrorMessages());
     
    @@ -422,12 +429,17 @@ private boolean processStyleTag(Element ele, Node parentNode) {
                      * break all CSS. To prevent that, we have this check.
                      */
     
    -                final String cleanHTML = cr.getCleanHTML();
    +                String cleanHTML = cr.getCleanHTML();
    +                cleanHTML = cleanHTML == null || cleanHTML.equals("") ? "/* */" : cleanHTML;
     
    -                if (cleanHTML == null || cleanHTML.equals("")) {
    -                    firstChild.setNodeValue("/* */");
    -                } else {
    -                    firstChild.setNodeValue(cleanHTML);
    +                ele.getFirstChild().setNodeValue(cleanHTML);
    +                /*
    +                 * Remove every other node after cleaning CSS, there will
    +                 * be only one node in the end, as it always should have.
    +                 */
    +                for (int i = 1; i < ele.getChildNodes().getLength(); i++) {
    +                    Node childNode = ele.getChildNodes().item(i);
    +                    ele.removeChild(childNode);
                     }
                 }
     
    
  • src/test/java/org/owasp/validator/html/test/AntiSamyTest.java+14 0 modified
    @@ -1702,5 +1702,19 @@ public void testGithubIssue151() throws ScanException, PolicyException {
             assertThat(result.getErrorMessages().size(), is(1));
             assertThat(result.getCleanHTML(), both(containsString("img")).and(not(containsString("CURSOR"))));
         }
    +
    +    @Test
    +    public void testSmuggledTagsInStyleContent() throws ScanException, PolicyException {
    +        // HTML tags may be smuggled into a style tag after parsing input to an internal representation.
    +        // If that happens, they should be treated as text content and not as children nodes.
    +
    +        Policy revised = policy.cloneWithDirective(Policy.USE_XHTML,"true");
    +        assertThat(as.scan("<style/>b<![cdata[</style><a href=javascript:alert(1)>test", revised, AntiSamy.DOM).getCleanHTML(), not(containsString("javascript")));
    +        assertThat(as.scan("<style/>b<![cdata[</style><a href=javascript:alert(1)>test", revised, AntiSamy.SAX).getCleanHTML(), not(containsString("javascript")));
    +
    +        Policy revised2 = policy.cloneWithDirective(Policy.USE_XHTML,"false");
    +        assertThat(as.scan("<select<style/>W<xmp<script>alert(1)</script>", revised2, AntiSamy.DOM).getCleanHTML(), not(containsString("script")));
    +        assertThat(as.scan("<select<style/>W<xmp<script>alert(1)</script>", revised2, AntiSamy.SAX).getCleanHTML(), not(containsString("script")));
    +    }
     }
     
    
  • src/test/java/org/owasp/validator/html/test/TestPolicy.java+1 1 modified
    @@ -43,7 +43,7 @@
      */
     public class TestPolicy extends InternalPolicy {
     
    -    protected TestPolicy(Policy.ParseContext parseContext) throws PolicyException {
    +    protected TestPolicy(Policy.ParseContext parseContext) {
             super(parseContext);
         }
     
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.