CVE-2023-46242 (Java, published 2023-11-07T19:15Z)
Description: value: XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. In affected versions it's possible to execute a content with the right of any user via a crafted URL. A user must have `programming` privileges in order to exploit this vulnerability. This issue has been patched in XWiki 14.10.7 and 15.2RC1. Users are advised to upgrade. There are no known workarounds for for this vulnerability.
Severity: nan (CVSS v3 base score: 8.8)
Weakness: CWE-352 \u2014 Cross-Site Request Forgery (CSRF)
The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
Repository: https://github.com/xwiki/xwiki-platform
Files changed:
xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/EditAction.java
xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/web/EditActionTest.java
Commit message: XWIKI-20386: CSRF privilege escalation/RCE via the edit action


Vulnerable code:
        // If the metadata is modified, modify the effective metadata author
        if (editedDocument.isMetaDataDirty()) {
            UserReference userReference =
                this.documentReferenceUserReferenceResolver.resolve(context.getUserReference());
            editedDocument.getAuthors().setEffectiveMetadataAuthor(userReference);
            editedDocument.getAuthors().setOriginalMetadataAuthor(userReference);
        }
        // If the content is modified, modify the content author
        if (editedDocument.isContentDirty()) {
            UserReference userReference =
                this.documentReferenceUserReferenceResolver.resolve(context.getUserReference());
            editedDocument.getAuthors().setContentAuthor(userReference);
    void documentAuthorsWhenDocumentExistAndContentIsModified() throws XWikiException

Fixed code:
import org.xwiki.csrf.CSRFToken;
    @Inject
    private CSRFToken csrf;

        // Check if the document in modified
        if (editedDocument.isMetaDataDirty() || editedDocument.isContentDirty()) {
            // If the document is modified make sure a valid CSRF is provided
            String token = context.getRequest().getParameter("form_token");
            if (!this.csrf.isTokenValid(token)) {
                // or make the document restricted
                editedDocument.setRestricted(true);
            }
            // If the metadata is modified, modify the effective metadata author
            if (editedDocument.isMetaDataDirty()) {
                UserReference userReference =
                    this.documentReferenceUserReferenceResolver.resolve(context.getUserReference());
                editedDocument.getAuthors().setEffectiveMetadataAuthor(userReference);
                editedDocument.getAuthors().setOriginalMetadataAuthor(userReference);
            }

            // If the content is modified, modify the content author
            if (editedDocument.isContentDirty()) {
                UserReference userReference =
                    this.documentReferenceUserReferenceResolver.resolve(context.getUserReference());
                editedDocument.getAuthors().setContentAuthor(userReference);
            }
import java.util.Map;

import org.xwiki.csrf.CSRFToken;
import static org.junit.jupiter.api.Assertions.assertEquals;
    @MockComponent
    private CSRFToken csrf;


        this.oldcore.getXWikiContext().setRequest(new XWikiServletRequestStub.Builder().
            setRequestParameters(Map.of("form_token", new String[] {"tokenvalue"})).build());
    void documentAuthorsWhenDocumentExistAndContentIsModifiedAndInvalidValidCSRF() throws XWikiException
    {
        documentAuthorsWhenDocumentExistAndContentIsModified(false);
    }

    @Test
    void documentAuthorsWhenDocumentExistAndContentIsModifiedAndValidCSRF() throws XWikiException
    {
        documentAuthorsWhenDocumentExistAndContentIsModified(true);
    }

    void documentAuthorsWhenDocumentExistAndContentIsModified(boolean validToken) throws XWikiException
        when(this.csrf.isTokenValid("tokenvalue")).thenReturn(validToken);

        assertEquals(!validToken, document.isRestricted());