CVE-2023-45137 (Other, published 2023-10-25T21:15Z)
Description: value: XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. `org.xwiki.platform:xwiki-platform-web` starting in version 3.1-milestone-2 and prior to version 13.4-rc-1, as well as `org.xwiki.platform:xwiki-platform-web-templates` prior to versions 14.10.12 and 15.5-rc-1, are vulnerable to cross-site scripting. When trying to create a document that already exists, XWiki displays an error message in the form for creating it. Due to missing escaping, this error message is vulnerable to raw HTML injection and thus XSS. The injected code is the document reference of the existing document so this requires that the attacker first creates a non-empty document whose name contains the attack code. This has been patched in `org.xwiki.platform:xwiki-platform-web` version 13.4-rc-1 and `org.xwiki.platform:xwiki-platform-web-templates` versions 14.10.12 and 15.5-rc-1 by adding the appropriate escaping. The vulnerable template file `createinline.vm` is part of XWiki's WAR and can be patched by manually applying the changes from the fix.
Severity: nan (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/xwiki/xwiki-platform
Files changed:
xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-templates/src/main/resources/templates/createinline.vm
xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-templates/src/test/java/org/xwiki/web/CreateInlinePageTest.java
Commit message: XWIKI-20961: Improve escaping for document exists error

* Add escaping for the document reference and add a test.


Vulnerable code:
        ["${existingDocumentReference}",
        String documentReference = "xwiki:space.</div>page";
        Object[] args = { documentReference };
        this.velocityManager.getVelocityContext().put("createException", invalidNameException);
        this.velocityManager.getVelocityContext().put("invalidNameReference", documentReference);
        Element errormessage = document.getElementsByClass("errormessage").first();
        String expectedMessage = String.format("entitynamevalidation.create.invalidname [%s]", documentReference);

Fixed code:
        [$escapetool.xml("${existingDocumentReference}"),
    private static final String DOCUMENT_REFERENCE = "xwiki:space.</div>page";

    private static final String CREATE_EXCEPTION_VELOCITY_KEY = "createException";

    private static final String ERROR_MESSAGE_CLASS = "errormessage";

        Object[] args = { DOCUMENT_REFERENCE };
        this.velocityManager.getVelocityContext().put(CREATE_EXCEPTION_VELOCITY_KEY, invalidNameException);
        this.velocityManager.getVelocityContext().put("invalidNameReference", DOCUMENT_REFERENCE);

        // Render the template.
        Document document = Jsoup.parse(this.templateManager.render(CREATE_INLINE_VM));
        Element errormessage = document.getElementsByClass(ERROR_MESSAGE_CLASS).first();
        assertNotNull(errormessage);
        String expectedMessage = String.format("entitynamevalidation.create.invalidname [%s]", DOCUMENT_REFERENCE);
        assertEquals(expectedMessage, errormessage.text());
    }

    /**
     * Test that when there is an exception about the document already existing, the name is correctly escaped.
     */
    @Test
    void testDocumentAlreadyExistsError() throws Exception
    {
        // Set "createException" to an XWikiException to simulate a document exists already error.
        String urlToDocument = "space/%3C%2Fdiv%3Epage";
        Object[] args = { DOCUMENT_REFERENCE };
        XWikiException documentAlreadyExistsException = new XWikiException(XWikiException.MODULE_XWIKI_STORE,
            XWikiException.ERROR_XWIKI_APP_DOCUMENT_NOT_EMPTY,
            "Cannot create document {0} because it already has content", null, args);
        this.velocityManager.getVelocityContext().put(CREATE_EXCEPTION_VELOCITY_KEY, documentAlreadyExistsException);
        this.velocityManager.getVelocityContext().put("existingDocumentReference", DOCUMENT_REFERENCE);
        Element errormessage = document.getElementsByClass(ERROR_MESSAGE_CLASS).first();
        String viewURL = String.format("/xwiki/bin/view/%s", urlToDocument);
        String editURL = String.format("/xwiki/bin/edit/%s", urlToDocument);
        String expectedMessage = String.format("core.create.page.error.docalreadyexists [%s, %s, %s]",
            DOCUMENT_REFERENCE, viewURL, editURL);