Critical severityNVD Advisory· Published Aug 19, 2024· Updated Aug 22, 2024
XWiki Platform allows XSS through XClass name in string properties
CVE-2024-43400
Description
XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. It is possible for a user without Script or Programming rights to craft a URL pointing to a page with arbitrary JavaScript. This requires social engineer to trick a user to follow the URL. This has been patched in XWiki 14.10.21, 15.5.5, 15.10.6 and 16.0.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.xwiki.platform:xwiki-platform-oldcoreMaven | >= 1.1.2, < 14.10.21 | 14.10.21 |
org.xwiki.platform:xwiki-platform-oldcoreMaven | >= 15.0-rc-1, < 15.5.5 | 15.5.5 |
org.xwiki.platform:xwiki-platform-oldcoreMaven | >= 15.6-rc-1, < 15.10.6 | 15.10.6 |
org.xwiki.platform:xwiki-platform-oldcoreMaven | >= 16.0.0-rc-1, < 16.0.0 | 16.0.0 |
Affected products
1- Range: >= 15.6-rc-1, < 15.10.2
Patches
127eca8423fc1XWIKI-21810: Improve suggest URL escaping in StringClass
2 files changed · +120 −17
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/objects/classes/StringClass.java+39 −17 modified@@ -19,7 +19,11 @@ */ package com.xpn.xwiki.objects.classes; +import java.util.LinkedHashMap; +import java.util.Map; + import org.apache.ecs.xhtml.input; +import org.xwiki.velocity.tools.EscapeTool; import org.xwiki.xml.XMLUtils; import com.xpn.xwiki.XWiki; @@ -30,6 +34,8 @@ import com.xpn.xwiki.objects.StringProperty; import com.xpn.xwiki.objects.meta.PropertyMetaClass; +import static org.apache.commons.lang.StringEscapeUtils.escapeJavaScript; + public class StringClass extends PropertyClass { private static final long serialVersionUID = 1L; @@ -89,7 +95,8 @@ public BaseProperty newProperty() } @Override - public void displayEdit(StringBuffer buffer, String name, String prefix, BaseCollection object, XWikiContext context) + public void displayEdit(StringBuffer buffer, String name, String prefix, BaseCollection object, + XWikiContext context) { input input = new input(); input.setAttributeFilter(new XMLAttributeValueFilter()); @@ -105,23 +112,9 @@ public void displayEdit(StringBuffer buffer, String name, String prefix, BaseCol input.setDisabled(isDisabled()); if (isPicker()) { - input.setClass("suggested"); - String path = ""; - XWiki xwiki = context.getWiki(); - path = xwiki.getURL("Main.WebHome", "view", context); - - String classname = this.getObject().getName(); - String fieldname = this.getName(); - String secondCol = "-", firstCol = "-"; - - String script = - "\"" + path + "?xpage=suggest&classname=" + classname + "&fieldname=" + fieldname + "&firCol=" - + firstCol + "&secCol=" + secondCol + "&\""; - String varname = "\"input\""; - input.setOnFocus("new ajaxSuggest(this, {script:" + script + ", varname:" + varname + "} )"); + displayPickerEdit(input); } - - buffer.append(input.toString()); + buffer.append(input); } @Override @@ -133,4 +126,33 @@ public void displayView(StringBuffer buffer, String name, String prefix, BaseCol buffer.append(XMLUtils.escapeElementText(property.toText())); } } + + private void displayPickerEdit(input input) + { + input.setClass("suggested"); + XWikiContext xWikiContext = getXWikiContext(); + XWiki xwiki = xWikiContext.getWiki(); + String path = xwiki.getURL("Main.WebHome", "view", xWikiContext); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(path); + stringBuilder.append('?'); + stringBuilder.append(new EscapeTool().url(getParametersMap())); + stringBuilder.append('&'); + input.setOnFocus(String.format("new ajaxSuggest(this, {script:\"%s\", varname:\"input\"} )", + escapeJavaScript(stringBuilder.toString()))); + } + + private Map<String, String> getParametersMap() + { + String dash = "-"; + // Using a linked hash map to keep the order of the keys stable when generating the query parameters, which + // is especially handy for testing, but could be useful in other scenarios. + Map<String, String> parameters = new LinkedHashMap<>(); + parameters.put("xpage", "suggest"); + parameters.put("classname", getObject().getName()); + parameters.put("fieldname", getName()); + parameters.put("firCol", dash); + parameters.put("secCol", dash); + return parameters; + } }
xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/objects/classes/StringClassTest.java+81 −0 added@@ -0,0 +1,81 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package com.xpn.xwiki.objects.classes; + +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.xwiki.model.reference.DocumentReference; + +import com.xpn.xwiki.XWikiContext; +import com.xpn.xwiki.test.MockitoOldcore; +import com.xpn.xwiki.test.component.XWikiDocumentFilterUtilsComponentList; +import com.xpn.xwiki.test.junit5.mockito.InjectMockitoOldcore; +import com.xpn.xwiki.test.junit5.mockito.OldcoreTest; +import com.xpn.xwiki.web.XWikiURLFactory; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +/** + * Test of {@link StringClass}. + * + * @version $Id$ + */ +@OldcoreTest +@XWikiDocumentFilterUtilsComponentList +class StringClassTest +{ + @InjectMockitoOldcore + private MockitoOldcore oldCore; + + @Mock + private XWikiURLFactory urlFactory; + + @Test + void displayEdit() + { + XWikiContext xWikiContext = this.oldCore.getXWikiContext(); + xWikiContext.setURLFactory(this.urlFactory); + when(this.oldCore.getSpyXWiki().getURL("Main.WebHome", "view", xWikiContext)).thenReturn("/a/b"); + + String fieldName = "test"; + String spaceName = "\" + alert(1) + \""; + String pageName = "WebHome"; + StringClass stringClass = new StringClass(); + stringClass.setPicker(true); + BaseClass baseClass = new BaseClass(); + stringClass.setObject(baseClass); + baseClass.setDocumentReference( + new DocumentReference(this.oldCore.getXWikiContext().getWikiId(), spaceName, pageName)); + stringClass.setName(fieldName); + StringBuffer stringBuffer = new StringBuffer(); + stringClass.displayEdit(stringBuffer, fieldName, spaceName + "." + pageName + "_0_", baseClass, + xWikiContext); + assertEquals("<input " + + "onfocus='new ajaxSuggest(this, {script:"\\/a\\/b?xpage=suggest&" + + "classname=%22%20%2B%20alert%281%29%20%2B%20%22.WebHome&fieldname=test&firCol=-&" + + "secCol=-&", varname:"input"} )' " + + "size='30' " + + "id='" + alert(1) + ".WebHome_0_test' " + + "class='suggested' " + + "name='" + alert(1) + ".WebHome_0_test' " + + "type='text'/>", stringBuffer.toString()); + } +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-wcg9-pgqv-xm5vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-43400ghsaADVISORY
- github.com/xwiki/xwiki-platform/commit/27eca8423fc1ad177518077a733076821268509cghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-platform/security/advisories/GHSA-wcg9-pgqv-xm5vghsax_refsource_CONFIRMWEB
- jira.xwiki.org/browse/XWIKI-21810ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.