VYPR
Moderate severityNVD Advisory· Published Jul 27, 2023· Updated Aug 2, 2024

XWiki Platform's obfuscated email addresses should not be sorted

CVE-2023-38509

Description

XWiki Platform is a generic wiki platform. In org.xwiki.platform:xwiki-platform-livetable-ui starting with version 3.5-milestone-1 and prior to versions 14.10.9 and 15.3-rc-1, the mail obfuscation configuration was not fully taken into account and is was still possible by obfuscated emails. This has been patched in XWiki 14.10.9 and XWiki 15.3-rc-1. A workaround is to modify the page XWiki.LiveTableResultsMacros following the patch.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-livetable-uiMaven
>= 3.5-milestone-1, < 14.10.914.10.9
org.xwiki.platform:xwiki-platform-livetable-uiMaven
>= 15.0, < 15.3-rc-115.3-rc-1

Affected products

1

Patches

2
1dfb6804d4d4

XWIKI-20601: Improved User Directory sorting

https://github.com/xwiki/xwiki-platformManuel LeducApr 6, 2023via ghsa
2 files changed · +85 1
  • xwiki-platform-core/xwiki-platform-livetable/xwiki-platform-livetable-ui/src/main/resources/XWiki/LiveTableResultsMacros.xml+3 1 modified
    @@ -20,7 +20,7 @@
      * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
     -->
     
    -<xwikidoc version="1.4" reference="XWiki.LiveTableResultsMacros" locale="">
    +<xwikidoc version="1.5" reference="XWiki.LiveTableResultsMacros" locale="">
       <web>XWiki</web>
       <name>LiveTableResultsMacros</name>
       <language/>
    @@ -138,6 +138,8 @@
       #set($order = "$!request.sort")
       #if ($order == 'doc.location')
         #set ($order = 'doc.fullName')
    +  #elseif ($order == 'email' &amp;&amp; $services.mail.general.shouldObfuscate())
    +    #set ($order = '')
       #end
       #set ($orderSql = '')
       #if($order != '')
    
  • xwiki-platform-core/xwiki-platform-livetable/xwiki-platform-livetable-ui/src/test/java/org/xwiki/livetable/LiveTableResultsTest.java+82 0 modified
    @@ -643,6 +643,88 @@ void obfuscateEmails(boolean obfuscate, String expectedHql, Map<String, Object>
             verify(this.query).bindValues(expectedBindValues);
         }
     
    +    public static Stream<Arguments> provideObfuscateEmailsSort()
    +    {
    +        return Stream.of(
    +            Arguments.of(
    +                true,
    +                ", BaseObject as obj   "
    +                    + "where obj.name=doc.fullName "
    +                    + "and obj.className = :className "
    +                    + "and doc.fullName not in (:classTemplate1, :classTemplate2)  ",
    +                Map.of(
    +                    "className", "Space.MyClass",
    +                    "classTemplate1", "Space.MyClassTemplate",
    +                    "classTemplate2", "Space.MyTemplate"
    +                ),
    +                "t...@mail.com",
    +                "t...@mail.com"
    +            ),
    +            Arguments.of(
    +                false,
    +                ", BaseObject as obj , StringProperty prop_email  "
    +                    + "where obj.name=doc.fullName "
    +                    + "and obj.className = :className "
    +                    + "and doc.fullName not in (:classTemplate1, :classTemplate2)  "
    +                    + "and obj.id=prop_email.id.id "
    +                    + "and prop_email.name = :prop_email_name   "
    +                    + "order by lower(prop_email.value) asc, prop_email.value asc",
    +                Map.of(
    +                    "className", "Space.MyClass",
    +                    "classTemplate1", "Space.MyClassTemplate",
    +                    "classTemplate2", "Space.MyTemplate",
    +                    "prop_email_name", "email"
    +                ),
    +                "<a href=\"mailto:test@mail.com\">test@mail.com</a>",
    +                "test@mail.com"
    +            )
    +        );
    +    }
    +
    +    @ParameterizedTest
    +    @MethodSource("provideObfuscateEmailsSort")
    +    void obfuscateEmailsSort(boolean obfuscate, String expectedHql, Map<String, Object> expectedBindValues,
    +        String expectedMail, String expectedMailValue) throws Exception
    +    {
    +        // TODO: We mock the mail configuration as it relies on document that are loaded through xar files from external
    +        //  modules, which is currently not possible (would it be loaded using a mandatory document initializer, it 
    +        //  would work though).
    +        when(this.generalMailConfiguration.shouldObfuscate()).thenReturn(obfuscate);
    +
    +        DocumentReference myClassReference = new DocumentReference("xwiki", "Space", "MyClass");
    +        XWikiDocument xClassDocument = new XWikiDocument(myClassReference);
    +        xClassDocument.getXClass().addEmailField("mail", "Email", 100);
    +        xClassDocument.getXClass().addTextField("name", "Name", 100);
    +        this.xwiki.saveDocument(xClassDocument, this.context);
    +
    +        XWikiDocument xObjectDocument = new XWikiDocument(new DocumentReference("xwiki", "Space", "MyObject"));
    +        xObjectDocument.setSyntax(XWIKI_2_1);
    +        BaseObject baseObject = xObjectDocument.newXObject(myClassReference, this.context);
    +        baseObject.set("mail", "test@mail.com", this.context);
    +        baseObject.set("name", "testName", this.context);
    +        this.xwiki.saveDocument(xObjectDocument, this.context);
    +
    +        setColumns("mail,name");
    +        setClassName("Space.MyClass");
    +        setSort("email", true);
    +
    +        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(1L);
    +        when(this.query.execute()).thenReturn(singletonList("Space.MyObject"));
    +
    +        renderPage();
    +
    +        List<Map<String, Object>> rows = getRows();
    +        assertEquals(expectedMail, StringUtils.trim((String) rows.get(0).get("mail")));
    +        assertEquals(expectedMailValue, rows.get(0).get("mail_value"));
    +
    +        verify(this.queryService).hql(expectedHql);
    +        verify(this.query).bindValues(expectedBindValues);
    +    }
    +
         //
         // Helper methods
         //
    
1dfb6804d4d4

XWIKI-20601: Improved User Directory sorting

https://github.com/xwiki/xwiki-platformManuel LeducApr 6, 2023via ghsa
2 files changed · +85 1
  • xwiki-platform-core/xwiki-platform-livetable/xwiki-platform-livetable-ui/src/main/resources/XWiki/LiveTableResultsMacros.xml+3 1 modified
    @@ -20,7 +20,7 @@
      * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
     -->
     
    -<xwikidoc version="1.4" reference="XWiki.LiveTableResultsMacros" locale="">
    +<xwikidoc version="1.5" reference="XWiki.LiveTableResultsMacros" locale="">
       <web>XWiki</web>
       <name>LiveTableResultsMacros</name>
       <language/>
    @@ -138,6 +138,8 @@
       #set($order = "$!request.sort")
       #if ($order == 'doc.location')
         #set ($order = 'doc.fullName')
    +  #elseif ($order == 'email' &amp;&amp; $services.mail.general.shouldObfuscate())
    +    #set ($order = '')
       #end
       #set ($orderSql = '')
       #if($order != '')
    
  • xwiki-platform-core/xwiki-platform-livetable/xwiki-platform-livetable-ui/src/test/java/org/xwiki/livetable/LiveTableResultsTest.java+82 0 modified
    @@ -643,6 +643,88 @@ void obfuscateEmails(boolean obfuscate, String expectedHql, Map<String, Object>
             verify(this.query).bindValues(expectedBindValues);
         }
     
    +    public static Stream<Arguments> provideObfuscateEmailsSort()
    +    {
    +        return Stream.of(
    +            Arguments.of(
    +                true,
    +                ", BaseObject as obj   "
    +                    + "where obj.name=doc.fullName "
    +                    + "and obj.className = :className "
    +                    + "and doc.fullName not in (:classTemplate1, :classTemplate2)  ",
    +                Map.of(
    +                    "className", "Space.MyClass",
    +                    "classTemplate1", "Space.MyClassTemplate",
    +                    "classTemplate2", "Space.MyTemplate"
    +                ),
    +                "t...@mail.com",
    +                "t...@mail.com"
    +            ),
    +            Arguments.of(
    +                false,
    +                ", BaseObject as obj , StringProperty prop_email  "
    +                    + "where obj.name=doc.fullName "
    +                    + "and obj.className = :className "
    +                    + "and doc.fullName not in (:classTemplate1, :classTemplate2)  "
    +                    + "and obj.id=prop_email.id.id "
    +                    + "and prop_email.name = :prop_email_name   "
    +                    + "order by lower(prop_email.value) asc, prop_email.value asc",
    +                Map.of(
    +                    "className", "Space.MyClass",
    +                    "classTemplate1", "Space.MyClassTemplate",
    +                    "classTemplate2", "Space.MyTemplate",
    +                    "prop_email_name", "email"
    +                ),
    +                "<a href=\"mailto:test@mail.com\">test@mail.com</a>",
    +                "test@mail.com"
    +            )
    +        );
    +    }
    +
    +    @ParameterizedTest
    +    @MethodSource("provideObfuscateEmailsSort")
    +    void obfuscateEmailsSort(boolean obfuscate, String expectedHql, Map<String, Object> expectedBindValues,
    +        String expectedMail, String expectedMailValue) throws Exception
    +    {
    +        // TODO: We mock the mail configuration as it relies on document that are loaded through xar files from external
    +        //  modules, which is currently not possible (would it be loaded using a mandatory document initializer, it 
    +        //  would work though).
    +        when(this.generalMailConfiguration.shouldObfuscate()).thenReturn(obfuscate);
    +
    +        DocumentReference myClassReference = new DocumentReference("xwiki", "Space", "MyClass");
    +        XWikiDocument xClassDocument = new XWikiDocument(myClassReference);
    +        xClassDocument.getXClass().addEmailField("mail", "Email", 100);
    +        xClassDocument.getXClass().addTextField("name", "Name", 100);
    +        this.xwiki.saveDocument(xClassDocument, this.context);
    +
    +        XWikiDocument xObjectDocument = new XWikiDocument(new DocumentReference("xwiki", "Space", "MyObject"));
    +        xObjectDocument.setSyntax(XWIKI_2_1);
    +        BaseObject baseObject = xObjectDocument.newXObject(myClassReference, this.context);
    +        baseObject.set("mail", "test@mail.com", this.context);
    +        baseObject.set("name", "testName", this.context);
    +        this.xwiki.saveDocument(xObjectDocument, this.context);
    +
    +        setColumns("mail,name");
    +        setClassName("Space.MyClass");
    +        setSort("email", true);
    +
    +        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(1L);
    +        when(this.query.execute()).thenReturn(singletonList("Space.MyObject"));
    +
    +        renderPage();
    +
    +        List<Map<String, Object>> rows = getRows();
    +        assertEquals(expectedMail, StringUtils.trim((String) rows.get(0).get("mail")));
    +        assertEquals(expectedMailValue, rows.get(0).get("mail_value"));
    +
    +        verify(this.queryService).hql(expectedHql);
    +        verify(this.query).bindValues(expectedBindValues);
    +    }
    +
         //
         // Helper methods
         //
    

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.