VYPR
High severityNVD Advisory· Published Aug 24, 2023· Updated Oct 2, 2024

XWiki Platform vulnerable to CSRF privilege escalation/RCE via the create action

CVE-2023-40572

Description

XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. The create action is vulnerable to a CSRF attack, allowing script and thus remote code execution when targeting a user with script/programming right, thus compromising the confidentiality, integrity and availability of the whole XWiki installation. When a user with script right views this image and a log message ERROR foo - Script executed! appears in the log, the XWiki installation is vulnerable. This has been patched in XWiki 14.10.9 and 15.4RC1 by requiring a CSRF token for the actual page creation.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-oldcoreMaven
>= 3.2-milestone-3, < 14.10.914.10.9
org.xwiki.platform:xwiki-platform-oldcoreMaven
>= 15.0-rc-1, < 15.4-rc-115.4-rc-1

Affected products

1

Patches

2
4b20528808d0

XWIKI-20849: Require a CSRF token in the create action

https://github.com/xwiki/xwiki-platformMichael HamannApr 18, 2023via ghsa
3 files changed · +80 93
  • xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/CreateAction.java+9 3 modified
    @@ -23,6 +23,7 @@
     import java.util.Locale;
     import java.util.Map;
     
    +import javax.inject.Inject;
     import javax.inject.Named;
     import javax.inject.Provider;
     import javax.inject.Singleton;
    @@ -96,6 +97,9 @@ public class CreateAction extends XWikiAction
          */
         private static final String LOCAL_SERIALIZER_HINT = "local";
     
    +    @Inject
    +    private CSRFToken csrf;
    +
         /**
          * The action to perform when creating a new page from a template.
          *
    @@ -185,9 +189,12 @@ public String render(XWikiContext context) throws XWikiException
             checkRights(newDocumentReference.getLastSpaceReference(), context);
     
             // Check if the document to create already exists and if it respects the name strategy
    +        // Also check the CSRF token.
             XWikiDocument newDocument = context.getWiki().getDocument(newDocumentReference, context);
             if (handler.isDocumentAlreadyExisting(newDocument) || handler.isDocumentPathTooLong(newDocumentReference)
    -            || !this.isEntityReferenceNameValid(newDocumentReference)) {
    +            || !this.isEntityReferenceNameValid(newDocumentReference)
    +            || !this.csrf.isTokenValid(context.getRequest().getParameter("form_token")))
    +        {
                 return CREATE_TEMPLATE;
             }
     
    @@ -334,8 +341,7 @@ private String getRedirectParameters(String parent, String title, String templat
                 redirectParams += "&title=" + Util.encodeURI(title, null);
             }
             // Both the save and the edit action might require a CSRF token
    -        CSRFToken csrf = Utils.getComponent(CSRFToken.class);
    -        redirectParams += "&form_token=" + Util.encodeURI(csrf.getToken(), null);
    +        redirectParams += "&form_token=" + Util.encodeURI(this.csrf.getToken(), null);
     
             return redirectParams;
         }
    
  • xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/web/CreateActionTest.java+70 90 modified
    @@ -72,6 +72,8 @@
     @OldcoreTest
     class CreateActionTest
     {
    +    private static final String CSRF_TOKEN_VALUE = "token4234343";
    +
         @InjectMockitoOldcore
         MockitoOldcore oldcore;
     
    @@ -125,6 +127,10 @@ public void beforeEach() throws Exception
             when(this.mockRequest.get("type")).thenReturn("plain");
     
             this.oldcore.getMocker().registerMockComponent(ObservationManager.class);
    +
    +        when(this.csrfToken.getToken()).thenReturn(CSRF_TOKEN_VALUE);
    +        when(this.csrfToken.isTokenValid(CSRF_TOKEN_VALUE)).thenReturn(true);
    +        when(this.mockRequest.getParameter("form_token")).thenReturn(CSRF_TOKEN_VALUE);
         }
     
         @Test
    @@ -137,8 +143,6 @@ void newDocumentFromURL() throws Exception
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Run the action
             String result = action.render(context);
    @@ -149,11 +153,42 @@ void newDocumentFromURL() throws Exception
             assertNull(result);
     
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki",
                 context);
         }
     
    +    @Test
    +    void newDocumentFromURLWithInvalidToken() throws Exception
    +    {
    +        // new document = xwiki:X.Y
    +        DocumentReference documentReference = new DocumentReference("xwiki", Arrays.asList("X"), "Y");
    +        XWikiDocument document = mock(XWikiDocument.class);
    +        when(document.getDocumentReference()).thenReturn(documentReference);
    +        when(document.isNew()).thenReturn(true);
    +        when(document.getLocalReferenceMaxLength()).thenReturn(255);
    +        this.context.setDoc(document);
    +
    +        // Submit an invalid token
    +        when(this.mockRequest.getParameter("form_token")).thenReturn("fakeToken");
    +
    +        // Run the action
    +        String result = this.action.render(this.context);
    +
    +        // The tests are below this line!
    +
    +        // Verify that the create template is rendered, so the UI is displayed for the user to re-submit with the
    +        // form token.
    +        assertEquals("create", result);
    +
    +        // Verify that we got until the token validation.
    +        verify(this.csrfToken).isTokenValid("fakeToken");
    +
    +        // We should not get this far so no redirect should be done, just the template will be rendered.
    +        verify(this.mockURLFactory, never()).createURL(any(), any(), any(), any(), any(), any(),
    +            any(XWikiContext.class));
    +    }
    +
         @Test
         void newDocumentButNonTerminalFromURL() throws Exception
         {
    @@ -164,8 +199,6 @@ void newDocumentButNonTerminalFromURL() throws Exception
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token432";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Pass the tocreate=nonterminal request parameter
             when(mockRequest.getParameter("tocreate")).thenReturn("nonterminal");
    @@ -178,8 +211,11 @@ void newDocumentButNonTerminalFromURL() throws Exception
             // Verify null is returned (this means the response has been returned)
             assertNull(result);
     
    +        // Verify that the token has been validated.
    +        verify(this.csrfToken).isTokenValid(CSRF_TOKEN_VALUE);
    +
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null,
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null,
                 "xwiki", context);
         }
     
    @@ -216,8 +252,6 @@ void newDocumentWebHomeTopLevelFromURL() throws Exception
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4234";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Run the action
             String result = action.render(context);
    @@ -229,7 +263,7 @@ void newDocumentWebHomeTopLevelFromURL() throws Exception
     
             // Note: The title is not "WebHome", but "X" (the space's name) to avoid exposing "WebHome" in the UI.
             verify(mockURLFactory).createURL("X", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=X&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=X&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -243,8 +277,6 @@ void newDocumentWebHomeFromURL() throws Exception
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token34342";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Run the action
             String result = action.render(context);
    @@ -257,7 +289,7 @@ void newDocumentWebHomeFromURL() throws Exception
             // Note1: The bebavior is the same for both a top level space and a child space WebHome.
             // Note2: The title is not "WebHome", but "Y" (the space's name) to avoid exposing "WebHome" in the UI.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null,
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null,
                 "xwiki", context);
         }
     
    @@ -271,8 +303,6 @@ void newDocumentWebHomeButTerminalFromURL() throws Exception
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4234343";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Pass the tocreate=terminal request parameter
             when(mockRequest.getParameter("tocreate")).thenReturn("terminal");
    @@ -287,7 +317,7 @@ void newDocumentWebHomeButTerminalFromURL() throws Exception
     
             // Note: We are creating X.Y instead of X.Y.WebHome because the tocreate parameter says "terminal".
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -355,8 +385,6 @@ void existingDocumentFromUI() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token424345";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y
             when(mockRequest.getParameter("spaceReference")).thenReturn("X");
    @@ -372,7 +400,7 @@ void existingDocumentFromUI() throws Exception
     
             // Note: We are creating X.Y.WebHome since we default to non-terminal documents.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null,
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null,
                 "xwiki", context);
         }
     
    @@ -386,8 +414,6 @@ void existingDocumentFromUICheckEscaping() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42124343";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X.Y&name=Z
             when(mockRequest.getParameter("spaceReference")).thenReturn("X.Y");
    @@ -403,7 +429,7 @@ void existingDocumentFromUICheckEscaping() throws Exception
     
             // Note: We are creating X.Y.Z.WebHome since we default to non-terminal documents.
             verify(mockURLFactory).createURL("X.Y.Z", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=Z&form_token=" + csrfTokenValue, null,
    +            "template=&parent=Main.WebHome&title=Z&form_token=" + CSRF_TOKEN_VALUE, null,
                 "xwiki", context);
         }
     
    @@ -417,8 +443,6 @@ void existingDocumentTerminalFromUI() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token424334466";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&tocreate=terminal
             when(mockRequest.getParameter("spaceReference")).thenReturn("X");
    @@ -435,7 +459,7 @@ void existingDocumentTerminalFromUI() throws Exception
     
             // Note: We are creating X.Y instead of X.Y.WebHome because the tocreate parameter says "terminal".
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -449,8 +473,6 @@ void existingDocumentTerminalFromUICheckEscaping() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token429988";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X.Y&name=Z&tocreate=termina
             when(mockRequest.getParameter("spaceReference")).thenReturn("X.Y");
    @@ -467,7 +489,7 @@ void existingDocumentTerminalFromUICheckEscaping() throws Exception
     
             // Note: We are creating X.Y.Z instead of X.Y.Z.WebHome because the tocreate parameter says "terminal".
             verify(mockURLFactory).createURL("X.Y", "Z", "edit",
    -            "template=&parent=Main.WebHome&title=Z&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=Z&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -581,8 +603,6 @@ void existingDocumentFromUITopLevelDocument() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42009";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI name=Y
             when(mockRequest.getParameter("name")).thenReturn("Y");
    @@ -597,7 +617,7 @@ void existingDocumentFromUITopLevelDocument() throws Exception
     
             // Note: We are creating X.Y.WebHome since we default to non-terminal documents.
             verify(mockURLFactory).createURL("Y", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -615,8 +635,6 @@ void existingDocumentFromUIDeprecated() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4233311";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI space=X&page=Y
             when(mockRequest.getParameter("space")).thenReturn("X");
    @@ -632,7 +650,7 @@ void existingDocumentFromUIDeprecated() throws Exception
     
             // Note: We are creating X.Y since the deprecated parameters were creating terminal documents by default.
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -646,8 +664,6 @@ void existingDocumentFromUIDeprecatedCheckEscaping() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token422112455";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI space=X.Y&page=Z
             when(mockRequest.getParameter("space")).thenReturn("X.Y");
    @@ -664,7 +680,7 @@ void existingDocumentFromUIDeprecatedCheckEscaping() throws Exception
             // Note1: The space parameter was previously considered as space name, not space reference, so it is escaped.
             // Note2: We are creating X\.Y.Z since the deprecated parameters were creating terminal documents by default.
             verify(mockURLFactory).createURL("X\\.Y", "Z", "edit",
    -            "template=&parent=Main.WebHome&title=Z&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=Z&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -678,8 +694,6 @@ void existingDocumentNonTerminalFromUIDeprecated() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42778900";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI space=X&tocreate=space
             when(mockRequest.getParameter("space")).thenReturn("X");
    @@ -695,7 +709,7 @@ void existingDocumentNonTerminalFromUIDeprecated() throws Exception
     
             // Note: We are creating X.WebHome because the tocreate parameter says "space".
             verify(mockURLFactory).createURL("X", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=X&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=X&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -709,8 +723,6 @@ void existingDocumentNonTerminalFromUIDeprecatedIgnoringPage() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4344119982";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI space=X&page=Y&tocreate=space
             when(mockRequest.getParameter("space")).thenReturn("X");
    @@ -728,7 +740,7 @@ void existingDocumentNonTerminalFromUIDeprecatedIgnoringPage() throws Exception
             // Note: We are creating X.WebHome instead of X.Y because the tocreate parameter says "space" and the page
             // parameter is ignored.
             verify(mockURLFactory).createURL("X", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=X&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=&parent=Main.WebHome&title=X&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -742,8 +754,6 @@ void existingDocumentNonTerminalFromUIDeprecatedCheckEscaping() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token425553";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI space=X.Y&tocreate=space
             when(mockRequest.getParameter("space")).thenReturn("X.Y");
    @@ -760,7 +770,7 @@ void existingDocumentNonTerminalFromUIDeprecatedCheckEscaping() throws Exception
             // Note1: The space parameter was previously considered as space name, not space reference, so it is escaped.
             // Note2: We are creating X\.Y.WebHome because the tocreate parameter says "space".
             verify(mockURLFactory).createURL("X\\.Y", "WebHome", "edit",
    -            "template=&parent=Main.WebHome&title=X.Y&form_token=" + csrfTokenValue, null,
    +            "template=&parent=Main.WebHome&title=X.Y&form_token=" + CSRF_TOKEN_VALUE, null,
                 "xwiki", context);
         }
     
    @@ -901,8 +911,6 @@ void existingDocumentFromUITemplateProviderSpecified() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42008766";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -924,7 +932,7 @@ void existingDocumentFromUITemplateProviderSpecified() throws Exception
     
             // Note: We are creating X.Y and using the template extracted from the template provider.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue, null, "xwiki",
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE, null, "xwiki",
                 context);
         }
     
    @@ -977,8 +985,6 @@ void existingDocumentFromUITemplateProviderSpecifiedRestrictionExistsOnParentSpa
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4221098";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X.Y.Z&name=W&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1004,7 +1010,7 @@ void existingDocumentFromUITemplateProviderSpecifiedRestrictionExistsOnParentSpa
             // document
             // Note2: We are creating X.Y.Z.W and using the template extracted from the template provider.
             verify(mockURLFactory).createURL("X.Y.Z.W", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=W&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=W&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1132,8 +1138,6 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws Excepti
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42988733";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Specifying a template provider in the URL: templateprovider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1155,7 +1159,7 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminal() throws Excepti
             // Note: We are creating the document X.Y as terminal and using a template, as specified in the template
             // provider.
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1169,8 +1173,6 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverriddenFromUIT
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4222113555";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Specifying a template provider in the URL: templateprovider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1193,7 +1195,7 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedTerminalOverriddenFromUIT
             // Note: We are creating the document X.Y.WebHome as non-terminal even if the template provider says otherwise.
             // Also using a template, as specified in the template provider.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1207,8 +1209,6 @@ void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exception
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4200983331";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Specifying a template provider in the URL: templateprovider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1230,7 +1230,7 @@ void newDocumentFromURLTemplateProviderSpecifiedNonTerminal() throws Exception
             // Note: We are creating the document X.Y as terminal and using a template, as specified in the template
             // provider.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1244,8 +1244,6 @@ void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenFromUITe
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42234456";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Specifying a template provider in the URL: templateprovider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1268,7 +1266,7 @@ void newDocumentFromURLTemplateProviderSpecifiedNonTerminalButOverriddenFromUITe
             // Note: We are creating the document X.Y as terminal and using a template, as specified in the template
             // provider.
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1283,8 +1281,6 @@ void existingDocumentFromUITemplateSpecified() throws Exception
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
     
             context.setDoc(document);
    -        String csrfTokenValue = "token4298833";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&template=XWiki.MyTemplate
             String templateDocumentFullName = "XWiki.MyTemplate";
    @@ -1307,7 +1303,7 @@ void existingDocumentFromUITemplateSpecified() throws Exception
     
             // Note: We are creating X.Y.WebHome and using the template specified in the request.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1321,8 +1317,6 @@ void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exception
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4244112";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1347,7 +1341,7 @@ void existingDocumentFromUITemplateProviderSpecifiedTerminal() throws Exception
             // Note: We are creating the document X.Y as terminal and using a template, as specified in the template
             // provider.
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1361,8 +1355,6 @@ void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFromUIToNon
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token422555987";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1388,7 +1380,7 @@ void existingDocumentFromUITemplateProviderSpecifiedTerminalOverridenFromUIToNon
             // Note: We are creating the document X.Y.WebHome as non-terminal, even if the template provider says otherwise.
             // Also using a template, as specified in the template provider.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1402,8 +1394,6 @@ void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws Excepti
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token424111553";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1428,7 +1418,7 @@ void existingDocumentFromUITemplateProviderSpecifiedNonTerminal() throws Excepti
             // Note: We are creating the document X.Y.WebHome as non-terminal and using a template, as specified in the
             // template provider.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1442,8 +1432,6 @@ void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenFromUITo
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token42008733";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1469,7 +1457,7 @@ void existingDocumentFromUITemplateProviderSpecifiedNonTerminalOverridenFromUITo
             // Note: We are creating the document X.Y as terminal, even if the template provider says otherwise.
             // Also using a template, as specified in the template provider.
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1483,8 +1471,6 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() throws E
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token423366";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Specifying a template provider in the URL: templateprovider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1507,7 +1493,7 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageType() throws E
             // property and it used the old "page" type instead. Also using a template, as specified in the template
             // provider.
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1522,8 +1508,6 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButOverridd
             when(document.isNew()).thenReturn(true);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token4265677398";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Specifying a template provider in the URL: templateprovider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1547,7 +1531,7 @@ void newDocumentWebHomeFromURLTemplateProviderSpecifiedButOldPageTypeButOverridd
             // specify a "terminal" property and it used the old "page" type, the UI explicitly asked for a non-terminal
             // document. Also using a template, as specified in the template provider.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1561,8 +1545,6 @@ void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() throws Exc
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token421198337";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1587,7 +1569,7 @@ void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceType() throws Exc
             // property and we fallback on the "type" property's value. Also using the template extracted from the template
             // provider.
             verify(mockURLFactory).createURL("X.Y", "WebHome", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    @@ -1601,8 +1583,6 @@ void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOverridenF
             when(document.isNew()).thenReturn(false);
             when(document.getLocalReferenceMaxLength()).thenReturn(255);
             context.setDoc(document);
    -        String csrfTokenValue = "token429866333";
    -        when(this.csrfToken.getToken()).thenReturn(csrfTokenValue);
     
             // Submit from the UI spaceReference=X&name=Y&templateProvider=XWiki.MyTemplateProvider
             String templateProviderFullName = "XWiki.MyTemplateProvider";
    @@ -1627,7 +1607,7 @@ void existingDocumentFromUITemplateProviderSpecifiedButOldSpaceTypeButOverridenF
             // Note: We are creating X.Y as terminal, since it is overriden from the UI, regardless of any backwards
             // compatibility resolutions. Also using the template extracted from the template provider.
             verify(mockURLFactory).createURL("X", "Y", "edit",
    -            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + csrfTokenValue,
    +            "template=XWiki.MyTemplate&parent=Main.WebHome&title=Y&form_token=" + CSRF_TOKEN_VALUE,
                 null, "xwiki", context);
         }
     
    
  • xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-templates/src/main/resources/templates/createinline.vm+1 0 modified
    @@ -276,6 +276,7 @@
       ## By the past, it was "xwiki/create.js" which created this field, but it was causing problems when the user sent the
       ## form before the JavaScript code was executed.
       <input type="hidden" name="templateprovider" id="templateprovider" value="" />
    +  <input type="hidden" name="form_token" value="$!{escapetool.xml($services.csrf.getToken())}"/>
     
       <div class='row'>
         ## Hide the first column when displayed in an AJAX call by clicking on a Wanted Link (because we know the target
    
123e5d7e4ca0

XWIKI-3945: Don't show blacklisted spaces only for simple users

https://github.com/xwiki/xwiki-platformvmassolJun 5, 2009via ghsa
1 file changed · +9 2
  • xwiki-platform-web/standard/src/main/webapp/templates/xwikivars.vm+9 2 modified
    @@ -8,8 +8,6 @@
     #set($spaceViewUrl = $spaceDoc.getURL("view"))
     #set($viewUrl = $doc.getURL("view"))
     #set($userObj = $!crtUserDoc.getObject("XWiki.XWikiUsers",0))
    -## TODO : replace this list by a hidden space feature.
    -#set($blacklistedSpaces = ["Import", "Panels", "Scheduler", "Stats", "XAppClasses", "XAppSheets", "XAppTemplates", "XWiki", "WatchCode", "WatchSheets", "XApp", "WatchAdmin", "Watch"])
     ## =====================================================================================
     ## Advanced users are:
     ## - super admin
    @@ -25,6 +23,15 @@
     #else
       #set($isAdvancedUser = ($userObj.getProperty("usertype").value == "Advanced"))
     #end
    +## ======================================================================================
    +## Compute list of spaces to blacklist so that simple users don't see them.
    +## TODO : replace this list by a hidden space feature.
    +## ======================================================================================
    +#if($hasAdmin || $isAdvancedUser)
    +  #set($blacklistedSpaces = [])
    +#else
    +  #set($blacklistedSpaces = ["Import", "Panels", "Scheduler", "Stats", "XAppClasses", "XAppSheets", "XAppTemplates", "XWiki", "WatchCode", "WatchSheets", "XApp", "WatchAdmin", "Watch"])
    +#end
     #set($parent ="<a href='$parentDoc.getURL()'>$xwiki.getXMLEncoded(${parentDoc.displayTitle})</a>")
     #if($tdoc)
     #set($headertitle = "<a href='$viewUrl'>$xwiki.getXMLEncoded(${tdoc.displayTitle})</a>")
    

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

6

News mentions

0

No linked articles in our index yet.