CVE-2021-32620: Incorrect Authorization (CWE-863)
value: XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. In versions prior to 11.10.13, 12.6.7, and 12.10.2, a user disabled on a wiki using email verification for registration canouldre-activate themself by using the activation link provided for his registration. The problem has been patched in the following versions of XWiki: 11.10.13, 12.6.7, 12.10.2, 13.0. It is possible to workaround the issue by resetting the `validkey` property of the disabled XWiki users. This can be done by editing the user profile with object editor.
CWE description: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
CVSS v3 base score: 8.8
Published: 2021-05-28T21:15Z
Repository: https://github.com/xwiki/xwiki-platform
Language: Java
Files changed: xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java, xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/XWikiTest.java
Commit date: 2020-12-16 15:43:13 +0100
Commit message: XWIKI-17942: Email validation check is not properly reset

  * Ensure to reset the validation email key once validated

Diff: diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java
index fb5b8327d4..3712d1b220 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java
@@ -3855,14 +3855,18 @@ public int validateUser(boolean withConfirmEmail, XWikiContext context) throws X
                 validationKey = ((PasswordClass) validationKeyClass).getEquivalentPassword(storedKey, validationKey);
             }
 
             // Compare the two keys
             if ((!storedKey.equals("") && (storedKey.equals(validationKey)))) {
+                // Ensure to remove the validation key value, so it cannot be used afterwards to enable back
+                // a disabled user.
+                userObject.setStringValue("validkey", "");
+                saveDocument(userDocument, context);
+
                 XWikiUser xWikiUser = new XWikiUser(userDocument.getDocumentReference());
                 xWikiUser.setDisabled(false, context);
                 xWikiUser.setEmailChecked(true, context);
-                saveDocument(userDocument, context);
 
                 if (withConfirmEmail) {
                     String email = userObject.getStringValue("email");
                     String password = userObject.getStringValue("password");
                     sendValidationEmail(username, password, email, request.getParameter("validkey"),
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/XWikiTest.java b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/XWikiTest.java
index 23184ac9fb..ed0b0f22d6 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/XWikiTest.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/XWikiTest.java
@@ -578,10 +578,12 @@ public void testValidationKeyStorage() throws Exception
         testUser.addObject("XWiki.XWikiUsers", userObject);
 
         this.xwiki.saveDocument(testUser, context);
 
         assertEquals(0, this.xwiki.validateUser(false, this.oldcore.getXWikiContext()));
+        XWikiDocument reloadedDocument = this.xwiki.getDocument(testUser, context);
+        assertEquals("", reloadedDocument.getObject("XWiki.XWikiUsers").getStringValue("validkey"));
 
         // Check with an incorrect plaintext key
         validationKey.setValue("wrong key");
         this.xwiki.saveDocument(testUser, context);
 

Vulnerable code:                 saveDocument(userDocument, context);
Fixed code:                 // Ensure to remove the validation key value, so it cannot be used afterwards to enable back
                // a disabled user.
                userObject.setStringValue("validkey", "");
                saveDocument(userDocument, context);

        XWikiDocument reloadedDocument = this.xwiki.getDocument(testUser, context);
        assertEquals("", reloadedDocument.getObject("XWiki.XWikiUsers").getStringValue("validkey"));