CVE-2024-31996 (published 2024-04-10T21:15Z)

XWiki Platform is a generic wiki platform. Starting in version 3.0.1 and prior to versions 4.10.19, 15.5.4, and 15.10-rc-1, the HTML escaping of escaping tool that is used in XWiki doesn't escape `{`, which, when used in certain places, allows XWiki syntax injection and thereby remote code execution. The vulnerability has been fixed in XWiki 14.10.19, 15.5.5, and 15.9 RC1. Apart from upgrading, there is no generic workaround. However, replacing `$escapetool.html` by `$escapetool.xml` in XWiki documents fixes the vulnerability. In a standard XWiki installation, the maintainers are only aware of the document `Panels.PanelLayoutUpdate` that exposes this vulnerability, patching this document is thus a workaround. Any extension could expose this vulnerability and might thus require patching, too.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/xwiki/xwiki-commons
commit_details: repo_url: https://github.com/xwiki/xwiki-commons
author: Pierre Jeanjean
author_date: 2023-10-20 17:01:41+02:00
msg: XCOMMONS-2828: Support curly braces in `EscapeTool.html()`
repository: repo_url: https://github.com/xwiki/xwiki-commons
repo_name: xwiki/xwiki-commons
description: Common Modules used by other XWiki top level projects
repo_language: Java
owner: xwiki
file_changes: filename: EscapeTool.java
change_type: ModificationType.MODIFY
diff: @@ -30,6 +30,8 @@
 import org.apache.commons.codec.net.QCodec;
 import org.apache.commons.codec.net.QuotedPrintableCodec;
 import org.apache.commons.text.StringEscapeUtils;
+import org.apache.commons.text.translate.CharSequenceTranslator;
+import org.apache.commons.text.translate.LookupTranslator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xwiki.xml.XMLUtils;
@@ -66,6 +68,13 @@ public class EscapeTool extends org.apache.velocity.tools.generic.EscapeTool
     /** And sign. */
     private static final String AND = "&";
 
+    private static final CharSequenceTranslator XWIKI_ESCAPE_HTML4 = StringEscapeUtils.ESCAPE_HTML4.with(
+        new LookupTranslator(Map.ofEntries(
+            Map.entry("{", "&lcub;"),
+            Map.entry("}", "&rcub;")
+        ))
+    );
+
     /**
      * Change the default key defined in {@link org.apache.velocity.tools.generic.EscapeTool}.
      */
@@ -74,6 +83,24 @@ public EscapeTool()
         setKey(DEFAULT_KEY);
     }
 
+    /**
+     * Escapes the HTML special characters in a <code>String</code> using HTML entities. This overrides the base
+     * implementation from Velocity in order to also escape characters potentially harmful in the context of XWiki,
+     * such as curly brackets.
+     *
+     * @param content the string to escape, may be {@code null}
+     * @return a new escaped {@code String}, {@code null} if {@code null} input
+     */
+    @Override
+    public String html(Object content)
+    {
+        if (content == null)
+        {
+            return null;
+        }
+        return XWIKI_ESCAPE_HTML4.translate(String.valueOf(content));
+    }
+
     /**
      * Escapes the XML special characters in a <code>String</code> using numerical XML entities. This overrides the base
      * implementation from Velocity, which is over-zealous and escapes any non-ASCII character. Since XWiki works with

programming_language: Java
filename: EscapeToolTest.java
change_type: ModificationType.MODIFY
diff: @@ -259,4 +259,12 @@ void velocity()
     {
         assertEquals("one${escapetool.h}${escapetool.h}two", this.tool.velocity("one##two"));        
     }
+
+    @Test
+    void html()
+    {
+        assertEquals("&lt;script&gt;alert(&quot;Hello, &amp;lt;World&amp;gt;!&quot;);&lt;/script&gt;&lcub;&lcub;"
+                + "/html&rcub;&rcub;",
+            this.tool.html("<script>alert(\"Hello, &lt;World&gt;!\");</script>{{/html}}"));
+    }
 }

programming_language: Java