CVE-2023-26476 (XML, published 2023-03-02T19:15Z)
Description: value: XWiki Platform is a generic wiki platform. Starting in version 3.2-m3, users can deduce the content of the password fields by repeated call to `LiveTableResults` and `WikisLiveTableResultsMacros`. The issue can be fixed by upgrading to versions 14.7-rc-1, 13.4.4, or 13.10.9 and higher, or in version >= 3.2M3 by applying the patch manually on `LiveTableResults` and `WikisLiveTableResultsMacros`.
Severity: nan (CVSS v3 base score: 7.5)
Weakness: CWE-307 \u2014 Improper Restriction of Excessive Authentication Attempts
The product does not implement sufficient measures to prevent multiple failed authentication attempts within a short time frame, making it more susceptible to brute force attacks.
Repository: https://github.com/xwiki/xwiki-platform
Files changed:
xwiki-platform-core/xwiki-platform-livetable/xwiki-platform-livetable-ui/src/main/resources/XWiki/LiveTableResultsMacros.xml
xwiki-platform-core/xwiki-platform-livetable/xwiki-platform-livetable-ui/src/test/java/org/xwiki/livetable/LiveTableResultsTest.java
xwiki-platform-core/xwiki-platform-wiki/xwiki-platform-wiki-ui/xwiki-platform-wiki-ui-mainwiki/src/main/resources/WikiManager/WikisLiveTableResultsMacros.xml
Commit message: XWIKI-19949: Livetable results allow reconstructing password hashes using 768 requests


Vulnerable code:
    #livetable_addColumnToQuery($colname)
    #livetable_addColumnToQuery($colname)

Fixed code:
    ## If a classname is defined and the class field corresponding to the column name,
    ## we check the type of the field and skip it if it's Password.
    #if ($className != '' &amp;&amp; $class.get($colname))
      #if ($class.get($colname).classType != 'Password')
        #livetable_addColumnToQuery($colname)
      #end
    #else
      #livetable_addColumnToQuery($colname)
    #end
import java.util.Collections;
import com.xpn.xwiki.objects.classes.BaseClass;
    @Test
    void cleanupAccessToPasswordFields() throws Exception
    {
        // Initialize an XClass with a password field.
        DocumentReference documentReference = new DocumentReference("xwiki", "XWiki", "MyClass");
        XWikiDocument xwikiDocument = this.xwiki.getDocument(documentReference, this.context);
        BaseClass xClass = xwikiDocument.getXClass();
        xClass.addPasswordField("password", "Password", 30);
        this.xwiki.saveDocument(xwikiDocument, this.context);

        when(this.queryService.hql(anyString())).thenReturn(this.query);
        when(this.query.setLimit(anyInt())).thenReturn(this.query);
        when(this.query.setOffset(anyInt())).thenReturn(this.query);
        when(this.query.bindValues(any(Map.class))).thenReturn(this.query);
        when(this.query.count()).thenReturn(0L);
        when(this.query.execute()).thenReturn(Collections.emptyList());

        this.request.put("classname", "XWiki.MyClass");
        this.request.put("password", "abcd");
        this.request.put("collist", "password");

        renderPage();

        verify(this.queryService).hql(", BaseObject as obj   "
            + "where obj.name=doc.fullName "
            + "and obj.className = :className "
            + "and doc.fullName not in (:classTemplate1, :classTemplate2)  ");
    }

    ## If a classname is defined and the class field corresponding to the column name,
    ## we check the type of the field and skip it if it's Password.
    #if ($className != '' &amp;&amp; $class.get($colname))
      #if ($class.get($colname).classType != 'Password')
        #livetable_addColumnToQuery($colname)
      #end
    #else
      #livetable_addColumnToQuery($colname)
    #end