VYPR
Critical severityNVD Advisory· Published Jun 23, 2023· Updated Nov 27, 2024

XWiki Platform vulnerable to privilege escalation (PR) from account through like LiveTableResults

CVE-2023-35152

Description

XWiki Platform is a generic wiki platform. Starting in version 12.9-rc-1 and prior to versions 14.4.8, 14.10.6, and 15.1, any logged in user can add dangerous content in their first name field and see it executed with programming rights. Leading to rights escalation. The vulnerability has been fixed on XWiki 14.4.8, 14.10.6, and 15.1. As a workaround, one may apply the patch manually.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-like-uiMaven
>= 12.9-rc-1, < 14.4.814.4.8
org.xwiki.platform:xwiki-platform-like-uiMaven
>= 14.5, < 14.10.614.10.6
org.xwiki.platform:xwiki-platform-like-uiMaven
>= 15.0-rc-1, < 15.115.1

Affected products

1

Patches

2
6ce2d04a5779

XWIKI-19900: Liked page whose FULLNAME contains dot(.) can not show in user profile.

https://github.com/xwiki/xwiki-platformManuel LeducFeb 20, 2023via ghsa
3 files changed · +126 1
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/pom.xml+27 0 modified
    @@ -70,5 +70,32 @@
           <scope>runtime</scope>
           <optional>true</optional>
         </dependency>
    +    <!-- Test dependencies. -->
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-test-page</artifactId>
    +      <version>${project.version}</version>
    +      <scope>test</scope>
    +    </dependency>
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-web-templates</artifactId>
    +      <version>${project.version}</version>
    +      <scope>test</scope>
    +    </dependency>
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-like-api</artifactId>
    +      <version>${project.version}</version>
    +      <scope>test</scope>
    +      <type>test-jar</type>
    +    </dependency>
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-user-default</artifactId>
    +      <version>${project.version}</version>
    +      <scope>test</scope>
    +      <type>test-jar</type>
    +    </dependency>
       </dependencies>
     </project>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/Code/LiveTableResultPage.xml+1 1 modified
    @@ -36,7 +36,7 @@
       <minorEdit>false</minorEdit>
       <syntaxId>xwiki/2.1</syntaxId>
       <hidden>true</hidden>
    -  <content>{{velocity}}
    +  <content>{{velocity wiki="false"}}
     #if ($xcontext.action == 'get')
       #template('hierarchy_macros.vm')
       #if("$!{request.xpage}" == 'plain')
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/test/java/org/xwiki/like/LiveTableResultPagePageTest.java+98 0 added
    @@ -0,0 +1,98 @@
    +/*
    + * See the NOTICE file distributed with this work for additional
    + * information regarding copyright ownership.
    + *
    + * This is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU Lesser General Public License as
    + * published by the Free Software Foundation; either version 2.1 of
    + * the License, or (at your option) any later version.
    + *
    + * This software is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    + * Lesser General Public License for more details.
    + *
    + * You should have received a copy of the GNU Lesser General Public
    + * License along with this software; if not, write to the Free
    + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
    + */
    +package org.xwiki.like;
    +
    +import java.util.List;
    +
    +import javax.inject.Named;
    +
    +import org.junit.jupiter.api.Test;
    +import org.xwiki.like.script.LikeScriptServiceComponentList;
    +import org.xwiki.model.reference.DocumentReference;
    +import org.xwiki.model.script.ModelScriptService;
    +import org.xwiki.ratings.RatingsManager;
    +import org.xwiki.ratings.internal.DefaultRating;
    +import org.xwiki.rendering.syntax.Syntax;
    +import org.xwiki.template.script.TemplateScriptService;
    +import org.xwiki.test.annotation.ComponentList;
    +import org.xwiki.test.junit5.mockito.MockComponent;
    +import org.xwiki.test.page.PageTest;
    +import org.xwiki.test.page.XWikiSyntax21ComponentList;
    +import org.xwiki.user.UserReferenceComponentList;
    +
    +import com.xpn.xwiki.doc.XWikiDocument;
    +
    +import net.sf.json.JSONObject;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.ArgumentMatchers.anyBoolean;
    +import static org.mockito.ArgumentMatchers.anyInt;
    +import static org.mockito.ArgumentMatchers.anyMap;
    +import static org.mockito.Mockito.when;
    +
    +/**
    + * Test of {@code XWiki.Like.Code.LiveTableResultPage}.
    + *
    + * @version $Id$
    + * @since 15.1
    + * @since 14.10.6
    + */
    +@XWikiSyntax21ComponentList
    +@LikeScriptServiceComponentList
    +@UserReferenceComponentList
    +@ComponentList({
    +    TemplateScriptService.class,
    +    ModelScriptService.class
    +})
    +class LiveTableResultPagePageTest extends PageTest
    +{
    +    private static final DocumentReference DOCUMENT_REFERENCE =
    +        new DocumentReference("xwiki", List.of("XWiki", "Like", "Code"), "LiveTableResultPage");
    +
    +    @MockComponent
    +    @Named("solr")
    +    private RatingsManager ratingsManager;
    +
    +    @Test
    +    void likedPageWithADot() throws Exception
    +    {
    +        DocumentReference likedPageReference = new DocumentReference("xwiki", "Space", "With.ADot");
    +
    +        // Create an empty page to be returned as a liked page.
    +        XWikiDocument likedDocument = this.xwiki.getDocument(likedPageReference, this.context);
    +        this.xwiki.saveDocument(likedDocument, this.context);
    +
    +        // The rating manager is mocked for now as the focus of the tests is currently not to test the likes indexing.
    +        when(this.ratingsManager.getRatings(anyMap(), anyInt(), anyInt(), any(RatingsManager.RatingQueryField.class),
    +            anyBoolean())).thenReturn(List.of(new DefaultRating("id1").setReference(likedPageReference)));
    +
    +        setOutputSyntax(Syntax.PLAIN_1_0);
    +        this.context.setAction("get");
    +
    +        this.request.put("offset", "1");
    +        this.request.put("reqNo", "1");
    +        this.request.put("limit", "10");
    +
    +        JSONObject object = renderJSONPage(DOCUMENT_REFERENCE);
    +        
    +        assertEquals("xwiki:Space.With\\.ADot", object.getJSONArray("rows").getJSONObject(0).getString("doc_fullName"));
    +    }
    +}
    
0993a7ab3c10

XWIKI-17733: Use a LiveTable to display the page liked in user profile

https://github.com/xwiki/xwiki-platformSimon UrliOct 13, 2020via ghsa
15 files changed · +298 42
  • xwiki-platform-core/pom.xml+8 3 modified
    @@ -494,24 +494,29 @@
                     <new>method java.util.Optional&lt;org.xwiki.ratings.Rating&gt; org.xwiki.ratings.script.AbstractScriptRatingsManager::setRating(org.xwiki.model.reference.EntityReference, int) @ org.xwiki.ratings.script.RatingsScriptService</new>
                     <justification>Redesign of Ratings API: use new best practices for script service return if type is nullable.</justification>
                   </item>
    -                <item>
    +              <item>
                     <code>java.method.parameterTypeChanged</code>
                     <old>parameter org.xwiki.ratings.script.RatingApi org.xwiki.ratings.script.RatingsScriptService::setRating(===org.xwiki.model.reference.DocumentReference===, org.xwiki.model.reference.DocumentReference, int)</old>
                     <new>parameter java.util.Optional&lt;org.xwiki.ratings.Rating&gt; org.xwiki.ratings.script.AbstractScriptRatingsManager::setRating(===org.xwiki.model.reference.EntityReference===, org.xwiki.user.UserReference, int) @ org.xwiki.ratings.script.RatingsScriptService</new>
                     <justification>Redesign of Ratings API: allow to set rating for any reference (not only DocumentReference)</justification>
                   </item>
    -                <item>
    +              <item>
                     <code>java.method.parameterTypeChanged</code>
                     <old>parameter org.xwiki.ratings.script.RatingApi org.xwiki.ratings.script.RatingsScriptService::setRating(org.xwiki.model.reference.DocumentReference, ===org.xwiki.model.reference.DocumentReference===, int)</old>
                     <new>parameter java.util.Optional&lt;org.xwiki.ratings.Rating&gt; org.xwiki.ratings.script.AbstractScriptRatingsManager::setRating(org.xwiki.model.reference.EntityReference, ===org.xwiki.user.UserReference===, int) @ org.xwiki.ratings.script.RatingsScriptService</new>
                     <justification>Redesign of Ratings API: use new best practices for specifying a user by using the UserReference.</justification>
                   </item>
    -                <item>
    +              <item>
                     <code>java.method.returnTypeChanged</code>
                     <old>method org.xwiki.ratings.script.RatingApi org.xwiki.ratings.script.RatingsScriptService::setRating(org.xwiki.model.reference.DocumentReference, org.xwiki.model.reference.DocumentReference, int)</old>
                     <new>method java.util.Optional&lt;org.xwiki.ratings.Rating&gt; org.xwiki.ratings.script.AbstractScriptRatingsManager::setRating(org.xwiki.model.reference.EntityReference, org.xwiki.user.UserReference, int) @ org.xwiki.ratings.script.RatingsScriptService</new>
                     <justification>Redesign of Ratings API: use new best practices for script service return if type is nullable.</justification>
                   </item>
    +              <item>
    +                <code>java.method.addedToInterface</code>
    +                <new>method long org.xwiki.like.LikeManager::countUserLikes(org.xwiki.user.UserReference) throws org.xwiki.like.LikeException</new>
    +                <justification>Unstable API.</justification>
    +              </item>
                 </revapi.ignore>
               </analysisConfiguration>
             </configuration>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-api/src/main/java/org/xwiki/like/internal/DefaultLikeManager.java+13 9 modified
    @@ -34,8 +34,6 @@
     import org.xwiki.cache.CacheManager;
     import org.xwiki.cache.config.LRUCacheConfiguration;
     import org.xwiki.component.annotation.Component;
    -import org.xwiki.component.manager.ComponentLifecycleException;
    -import org.xwiki.component.phase.Disposable;
     import org.xwiki.component.phase.Initializable;
     import org.xwiki.component.phase.InitializationException;
     import org.xwiki.like.LikeConfiguration;
    @@ -65,7 +63,7 @@
      */
     @Component
     @Singleton
    -public class DefaultLikeManager implements LikeManager, Initializable, Disposable
    +public class DefaultLikeManager implements LikeManager, Initializable
     {
         private static final int DEFAULT_LIKE_VOTE = 1;
     
    @@ -126,12 +124,6 @@ public void initialize() throws InitializationException
             }
         }
     
    -    @Override
    -    public void dispose() throws ComponentLifecycleException
    -    {
    -        //this.authorizationManager.
    -    }
    -
         private String getExistCacheKey(UserReference source, EntityReference target)
         {
             return String.format("%s_%s",
    @@ -176,6 +168,18 @@ public List<EntityReference> getUserLikes(UserReference source, int offset, int
             }
         }
     
    +    @Override
    +    public long countUserLikes(UserReference source) throws LikeException
    +    {
    +        try {
    +            return this.ratingsManager.countRatings(
    +                Collections.singletonMap(RatingsManager.RatingQueryField.USER_REFERENCE, source));
    +        } catch (RatingsException e) {
    +            throw new LikeException(
    +                String.format("Error when trying to count user likes for user [%s]", source), e);
    +        }
    +    }
    +
         @Override
         public long getEntityLikes(EntityReference target) throws LikeException
         {
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-api/src/main/java/org/xwiki/like/LikeManager.java+13 0 modified
    @@ -58,6 +58,17 @@ public interface LikeManager
          */
         List<EntityReference> getUserLikes(UserReference source, int offset, int limit) throws LikeException;
     
    +    /**
    +     * Retrieve the total number of likes performed by a user.
    +     *
    +     * @param source the user who performs the likes to count.
    +     * @return the total number of likes performed.
    +     * @throws LikeException in case of problem when getting the information.
    +     * @since 12.9RC1
    +     */
    +    @Unstable
    +    long countUserLikes(UserReference source) throws LikeException;
    +
         /**
          * Retrieve like information a specific entity.
          *
    @@ -95,7 +106,9 @@ public interface LikeManager
          * @param limit the limit used for pagination.
          * @return a list of user references of users who liked this page.
          * @throws LikeException in case of problem for performing the query.
    +     * @since 12.9RC1
          */
    +    @Unstable
         List<UserReference> getLikers(EntityReference target, int offset, int limit) throws LikeException;
     
         /**
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-api/src/main/java/org/xwiki/like/script/LikeScriptService.java+20 0 modified
    @@ -214,6 +214,26 @@ public List<EntityReference> getUserLikes(UserReference userReference, int offse
             return Collections.emptyList();
         }
     
    +    /**
    +     * Count the number of likes performed by the given user.
    +     *
    +     * @param userReference the user for whom to count likes.
    +     * @return the number of likes performed.
    +     * @since 12.9RC1
    +     */
    +    @Unstable
    +    public Optional<Long> countUserLikes(UserReference userReference)
    +    {
    +        Optional<Long> result = Optional.empty();
    +        try {
    +            result = Optional.of(this.likeManager.countUserLikes(userReference));
    +        } catch (LikeException e) {
    +            this.logger.warn("Error while counting likes for user [{}]", userReference,
    +                ExceptionUtils.getRootCause(e));
    +        }
    +        return result;
    +    }
    +
         /**
          * Determine if the current user already liked the given reference.
          * @param entityReference the reference for which to check if the current liked it or not already.
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-api/src/main/resources/templates/likers.vm+91 14 modified
    @@ -17,19 +17,96 @@
     ## Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
     ## 02110-1301 USA, or see the FSF site: http://www.fsf.org.
     ## ---------------------------------------------------------------------------
    -#set ($likers = $services.like.getLikers($doc, 0, 50))
    -<div id="document-title"><h1>$services.localization.render('like.likers.title', [$doc.title])</h1></div>
    -<div id="likers-content">
    -    #if ($likers.isEmpty())
    -        $services.localization.render('like.likers.empty')
    +#if ($request.livetable == "true")
    +    #macro (displayUserAliasWithAvatar $userReference $disabled)
    +    <div class="user#if ($disabled) disabled#end" data-reference="$escapetool.xml($userReference)">
    +    <span class="user-avatar-wrapper">
    +      #getUserAvatarURL($userReference $avatarURL 120)
    +      <img class="user-avatar" src="$escapetool.xml($avatarURL.url)" />
    +    </span>
    +      <a href="$xwiki.getURL($userReference)">$escapetool.xml($userReference.name)</a>
    +    </div>
    +    #end
    +    $response.setContentType('application/json')
    +    #set ($documentReference = $doc.documentReference)
    +    ##==============================
    +    ## Offset = item # at which to start displaying data
    +    ##==============================
    +    #set($offset = $numbertool.toNumber($request.get('offset')))
    +    ## offset starts from 0 in velocity and 1 in javascript
    +    #set($offset = $offset - 1)
    +    #if($offset < 0)
    +        #set($offset = 0)
    +    #end
    +    ##==================
    +    ## Limit = # of items to display
    +    ##==================
    +    #set($limit = $numbertool.toNumber($request.get('limit')))
    +    ##==========
    +    ## Sort direction
    +    ##==========
    +    #set($order = "$!request.sort")
    +    #if($order != '')
    +        #set($orderDirection = "$!{request.get('dir').toLowerCase()}")
    +        #if("$!orderDirection" != '' && "$!orderDirection" != 'asc')
    +            #set($orderDirection = 'desc')
    +        #end
    +    #end
    +    #set ($likeRecords = $services.like.getLikers($documentReference, $offset, $limit))
    +    #set ($userRows = [])
    +    #foreach($userReference in $likeRecords)
    +        #set ($grayed = $xcontext.userReference == $userReference.reference)
    +        #set ($userDoc = $xwiki.getDocument($userReference.reference))
    +        #set ($userProperties = $services.user.getProperties($userReference))
    +        #set ($userObject = $user.getObject('XWiki.XWikiUsers'))
    +        #set ($row = {
    +            'grayed': $grayed,
    +            'doc_fullName': $userDoc.fullName,
    +            'doc_wiki': $userDoc.wiki,
    +            'doc_url': $userDoc.getURL(),
    +            'doc_viewable': $services.security.authorization.hasAccess('view', $userDoc.documentReference),
    +            'name': "#displayUserAliasWithAvatar($userDoc.documentReference $disabled)",
    +            'first_name': $userProperties.firstName,
    +            'last_name': $userProperties.lastName
    +        })
    +        #set ($discard = $userRows.add($row))
    +    #end
    +    ## ===
    +    ## JSON
    +    ## ===
    +    #set ($newOffset = $offset + 1)
    +    #set ($optLikesNumber = $services.like.getLikes($documentReference))
    +    #if ($optLikesNumber.isPresent())
    +      #set ($totalRows = $optLikesNumber.get())
         #else
    -      <p>
    -          $services.localization.render('like.likers.number', [$likers.size()])
    -      </p>
    -      <ul>
    -          #foreach($liker in $likers)
    -            <li>#displayUserLink($liker)</li>
    -          #end
    -      </ul>
    +      #set ($totalRows = $likeRecords.size())
         #end
    -</div>
    \ No newline at end of file
    +    {
    +        "totalrows": $totalRows,
    +        "returnedrows":  $likeRecords.size(),
    +        "offset": $newOffset,
    +        "reqNo": $numbertool.toNumber($request.reqNo),
    +        "rows": $jsontool.serialize($userRows)
    +    }
    +#else
    +    <h1>$escapetool.xml($services.localization.render('like.likers.title', [$doc.plainTitle]))</h1>
    +    #set($columns = ["name", "first_name", "last_name"])
    +    #set($columnsProperties = {
    +        "name" : { "type" : "text", "sortable": false, "filterable": false, "html": true },
    +        "first_name" : { "type" : "text", "sortable": false, "filterable": false},
    +        "last_name" : { "type" : "text", "sortable": false, "filterable": false}
    +    })
    +    #set ($queryParams = {
    +        "livetable": "true",
    +        "xpage": "likers",
    +        "outputSyntax": "plain"
    +    })
    +    ## We rely on the same column name than the Users administration, so we use same translation prefix for now.
    +    #set($options = {
    +        'url': $doc.getURL('get', $escapetool.url($queryParams)),
    +        'outputOnlyHtml': true,
    +        'translationPrefix' : "xe.admin.users."
    +    })
    +
    +    #livetable("likers" $columns $columnsProperties $options)
    +#end
    \ No newline at end of file
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-api/src/test/java/org/xwiki/like/internal/DefaultLikeManagerTest.java+10 0 modified
    @@ -308,4 +308,14 @@ void getLikers() throws Exception
             assertEquals(Arrays.asList(userReference1, userReference2, userReference3),
                 this.defaultLikeManager.getLikers(this.target, 12, 4));
         }
    +
    +    @Test
    +    void countUserLikes() throws Exception
    +    {
    +        when(this.ratingsManager.countRatings(
    +            Collections.singletonMap(RatingsManager.RatingQueryField.USER_REFERENCE, this.userReference)))
    +            .thenReturn(42L);
    +
    +        assertEquals(42L, this.defaultLikeManager.countUserLikes(this.userReference));
    +    }
     }
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-api/src/test/java/org/xwiki/like/script/LikeScriptServiceTest.java+20 0 modified
    @@ -20,6 +20,7 @@
     package org.xwiki.like.script;
     
     import java.util.Arrays;
    +import java.util.List;
     import java.util.Locale;
     import java.util.Optional;
     
    @@ -54,6 +55,7 @@
     import static org.junit.jupiter.api.Assertions.assertFalse;
     import static org.junit.jupiter.api.Assertions.assertSame;
     import static org.junit.jupiter.api.Assertions.assertTrue;
    +import static org.mockito.Mockito.mock;
     import static org.mockito.Mockito.times;
     import static org.mockito.Mockito.verify;
     import static org.mockito.Mockito.when;
    @@ -284,4 +286,22 @@ void cleanCache()
                 Locale.ROOT);
             verify(this.asyncRendererCache).cleanCache(uixReference);
         }
    +
    +    @Test
    +    void countUserLikes() throws LikeException
    +    {
    +        when(this.likeManager.countUserLikes(userReference)).thenReturn(43L);
    +        assertEquals(Optional.of(43L), this.likeScriptService.countUserLikes(this.userReference));
    +    }
    +
    +    @Test
    +    void getUserLikes() throws LikeException
    +    {
    +        List<EntityReference> expectedList = Arrays.asList(
    +            mock(EntityReference.class),
    +            mock(EntityReference.class),
    +            mock(EntityReference.class));
    +        when(this.likeManager.getUserLikes(this.userReference, 2, 32)).thenReturn(expectedList);
    +        assertEquals(expectedList, this.likeScriptService.getUserLikes(this.userReference, 2, 32));
    +    }
     }
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/LikeTranslations.de.xml+0 1 modified
    @@ -57,5 +57,4 @@ XWiki.Like.LikeConfigurationClass_alwaysDisplayButton="Gefällt mir" Schaltfläc
     XWiki.Like.LikeConfigurationClass_alwaysDisplayButton.hint=Die "Gefällt mir" Schaltfläche immer anzeigen - selbst wenn der Nutzer kein Recht hat diese zu benutzen. Anschalten, um die Anzahl der "Gefällt mir" immer anzuzeigen.
     XWiki.Like.LikeConfigurationClass_cacheCapacity=Cache-Größe
     XWiki.Like.LikeConfigurationClass_cacheCapacity.hint=Anzahl der "Gefällt mir"-Informationen im Cache. Sie müssen XWiki neustarten, damit veränderte Einstellungen angewendet werden.</content>
    -  
     </xwikidoc>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/LikeTranslations.es.xml+0 1 modified
    @@ -57,5 +57,4 @@ XWiki.Like.LikeConfigurationClass_alwaysDisplayButton=Mostrar siempre el botón
     XWiki.Like.LikeConfigurationClass_alwaysDisplayButton.hint=Mostrar el botón incluso si el usuario no tiene derecho de interaccionar con él.  Úsalo si deseas mostrar siempre el contador de "Me gusta".
     XWiki.Like.LikeConfigurationClass_cacheCapacity=Capacidad de la caché
     XWiki.Like.LikeConfigurationClass_cacheCapacity.hint=Número de información de "Me gusta" guardada en la caché. Ten en cuenta que tienes que reiniciar XWiki para que se activen los cambios de esta opción.</content>
    -  
     </xwikidoc>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/LikeTranslations.fr.xml+0 1 modified
    @@ -57,5 +57,4 @@ XWiki.Like.LikeConfigurationClass_alwaysDisplayButton=Toujours afficher le bouto
     XWiki.Like.LikeConfigurationClass_alwaysDisplayButton.hint=Afficher le bouton même si l'utilisateur n'a pas les droits pour intéragir avec. Utilisez cette option si vous souhaitez toujours afficher le compteur de J'aime.
     XWiki.Like.LikeConfigurationClass_cacheCapacity=Capacité du Cache
     XWiki.Like.LikeConfigurationClass_cacheCapacity.hint=Nombre d'information J'aime à conserver dans le cache. Notez que vous devrez redémarrer XWiki pour que cette option soit prise en compte.</content>
    -  
     </xwikidoc>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/LikeTranslations.no.xml+0 1 modified
    @@ -57,5 +57,4 @@ XWiki.Like.LikeConfigurationClass_alwaysDisplayButton=Vis alltid Liker-knappen
     XWiki.Like.LikeConfigurationClass_alwaysDisplayButton.hint=Vis knappen selv om brukeren ikke har rettigheter til å bruke den. Bruk hvis du alltid vil vise Liker-telleren.
     XWiki.Like.LikeConfigurationClass_cacheCapacity=Hurtigbufferkapasitet
     XWiki.Like.LikeConfigurationClass_cacheCapacity.hint=Antall Liker-informasjon som er lagret i hurtigbufferen. Merk at du må starte XWiki på nytt for at dette valget skal aktiveres.</content>
    -  
     </xwikidoc>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/LikeTranslations.ru.xml+0 1 modified
    @@ -57,5 +57,4 @@ like.newlike.error=Ошибка при попытке поставить "Нра
     ### Missing: XWiki.Like.LikeConfigurationClass_alwaysDisplayButton.hint=Display the button even if the user doesn't have the rights to interact with it. Use it if you wish to always display the Likes counter.
     ### Missing: XWiki.Like.LikeConfigurationClass_cacheCapacity=Cache capacity
     ### Missing: XWiki.Like.LikeConfigurationClass_cacheCapacity.hint=Number of Like information kept in cache. Note that you have to restart XWiki for this option change to be taken into account.</content>
    -  
     </xwikidoc>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/LikeTranslations.xml+4 1 modified
    @@ -52,7 +52,10 @@ like.button.title.like=Click to like the current page. Number of likes on this p
     like.button.title.unlike=Click to unlike the current page. Number of likes on this page: {0}.
     like.likers.empty=No one likes this page yet.
     like.likers.number={0} person(s) like this page:
    -like.likers.title=Likes on {0}
    +like.likers.title=Likers of {0}
    +like.livetable.column.title=Title
    +like.livetable.column.location=Location
    +like.livetable.column.likes=Likes
     XWiki.Like.LikeConfigurationClass_alwaysDisplayButton=Always display Like button
     XWiki.Like.LikeConfigurationClass_alwaysDisplayButton.hint=Display the button even if the user doesn't have the rights to interact with it. Use it if you wish to always display the Likes counter.
     XWiki.Like.LikeConfigurationClass_cacheCapacity=Cache capacity
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/LikeViewersMenuUIX.xml+1 1 modified
    @@ -183,4 +183,4 @@
           <scope>wiki</scope>
         </property>
       </object>
    -</xwikidoc>
    \ No newline at end of file
    +</xwikidoc>
    
  • xwiki-platform-core/xwiki-platform-like/xwiki-platform-like-ui/src/main/resources/XWiki/Like/UserProfileUIX.xml+118 9 modified
    @@ -36,7 +36,96 @@
       <minorEdit>false</minorEdit>
       <syntaxId>xwiki/2.1</syntaxId>
       <hidden>true</hidden>
    -  <content/>
    +  <content>{{velocity}}
    +#if ($request.livetable == "true")
    +  #template('hierarchy_macros.vm')
    +  #if("$!{request.xpage}" == 'plain')
    +    $response.setContentType('application/json')
    +  #end
    +  #set ($documentReference = $services.model.resolveDocument($request.user))
    +  ##==============================
    +  ## Offset = item # at which to start displaying data
    +  ##==============================
    +  #set($offset = $numbertool.toNumber($request.get('offset')))
    +  ## offset starts from 0 in velocity and 1 in javascript
    +  #set($offset = $offset - 1)
    +  #if($offset &lt; 0)
    +    #set($offset = 0)
    +  #end
    +  ##==================
    +  ## Limit = # of items to display
    +  ##==================
    +  #set($limit = $numbertool.toNumber($request.get('limit')))
    +  #set ($likedPages = $services.like.getUserLikes($documentReference, $offset, $limit))
    +  #set ($optUserLikes = $services.like.countUserLikes($documentReference))
    +  #if ($optUserLikes.isPresent())
    +    #set ($totalRows = $optUserLikes.get())
    +  #else
    +    #set ($totalRows = $likedPages.size())
    +  #end
    +  ##==========
    +  ## Sort direction
    +  ##==========
    +  #set($order = "$!request.sort")
    +  #if($order != '')
    +    #set($orderDirection = "$!{request.get('dir').toLowerCase()}")
    +    #if("$!orderDirection" != '' &amp;&amp; "$!orderDirection" != 'asc')
    +      #set($orderDirection = 'desc')
    +    #end
    +  #end
    +  #set ($pagesRows = [])
    +  #foreach($likedPage in $likedPages)
    +    #set ($likedDoc = $xwiki.getDocument($likedPage))
    +    #set ($optDocumentLikes = $services.like.getLikes($likedPage))
    +    #if ($optDocumentLikes.isPresent())
    +      #set ($documentLikes = $optDocumentLikes.get())
    +    #else
    +      #set ($documentLikes = "N/A")
    +    #end
    +    ## code inspired from getdocuments.vm
    +    #set ($viewable = $xwiki.hasAccessLevel('view', $xcontext.user, $services.model.serialize($likedPage, "default")))
    +    #set ($row = {'doc_viewable' : $viewable})
    +    #if (!$viewable)
    +      #set ($discard = $row.put('doc_fullName', $likedDoc.fullName))
    +    #else
    +      #set ($translatedDoc = $likedDoc.translatedDocument)
    +      #set ($fullname = $services.model.serialize($likedDoc.documentReference, 'default'))
    +      #set ($discard = $row.put('doc_name', $likedDoc.documentReference.name))
    +      #set ($discard = $row.put('doc_fullName', $fullname))
    +      #set ($location = "#hierarchy($likedDoc.documentReference, {'limit': 5, 'plain': false, 'local': true, 'displayTitle': false})")
    +      #set ($discard = $row.put('doc_location', $location))
    +      #set ($discard = $row.put('doc_space', $likedDoc.space))
    +      #set ($discard = $row.put('doc_url', $xwiki.getURL($likedDoc)))
    +      #set ($discard = $row.put('doc_space_url', $xwiki.getURL($services.model.createDocumentReference($!likedDoc.wiki, $!likedDoc.space, 'WebHome'))))
    +      #set ($discard = $row.put('doc_wiki', $likedDoc.wiki))
    +      #set ($discard = $row.put('doc_wiki_url', $xwiki.getURL($services.model.resolveDocument('', 'default', $likedDoc.documentReference.extractReference('WIKI')))))
    +      #set ($discard = $row.put('doc_author_url', $xwiki.getURL($translatedDoc.author)))
    +      #set ($discard = $row.put('doc_date', $xwiki.formatDate($translatedDoc.date)))
    +      #set ($discard = $row.put('doc_title', $translatedDoc.plainTitle))
    +      #set ($rawTitle = $translatedDoc.title)
    +      #if ($rawTitle != $row['doc_title'])
    +        #set ($discard = $row.put('doc_title_raw', $rawTitle))
    +      #end
    +      #set ($discard = $row.put('doc_author', $xwiki.getUserName($translatedDoc.author, false)))
    +      #set ($discard = $row.put('doc_creationDate', $xwiki.formatDate($translatedDoc.creationDate)))
    +      #set ($discard = $row.put('doc_creator', $xwiki.getUserName($translatedDoc.creator, false)))
    +    #end
    +    #set ($discard = $row.put('like', $documentLikes))
    +    #set ($discard = $pagesRows.add($row))
    +  #end
    +  #set ($newOffset = $offset + 1)
    +  ## ===
    +  ## JSON
    +  ## ===
    +  {
    +    "totalrows": $totalRows,
    +    "returnedrows":  $pagesRows.size(),
    +    "offset": $newOffset,
    +    "reqNo": $numbertool.toNumber($request.reqNo),
    +    "rows": $jsontool.serialize($pagesRows)
    +  }
    +#end
    +{{/velocity}}</content>
       <object>
         <name>XWiki.Like.UserProfileUIX</name>
         <number>0</number>
    @@ -66,6 +155,8 @@
             <cache>0</cache>
             <disabled>0</disabled>
             <displayType>select</displayType>
    +        <freeText>forbidden</freeText>
    +        <largeStorage>0</largeStorage>
             <multiSelect>1</multiSelect>
             <name>async_context</name>
             <number>4</number>
    @@ -154,21 +245,39 @@
         </property>
         <property>
           <async_context>
    +        <value>doc.reference</value>
             <value>user</value>
    -        <value>wiki</value>
           </async_context>
         </property>
         <property>
    -      <async_enabled>1</async_enabled>
    +      <async_enabled>0</async_enabled>
         </property>
         <property>
           <content>{{velocity}}
    -#set ($likedReferences = $services.like.getUserLikes($services.user.currentUserReference, 0, 50))
    -|=Page
    -#foreach ($likeReference in $likedReferences)
    -  #set ($likedDocument = $xwiki.getDocument($likeReference))
    -  |[[$likedDocument.title&gt;&gt;$services.model.serialize($likeReference)]]
    -#end
    +=$escapetool.xml($services.localization.render("like.userprofile.menu"))=
    +#set($columns = ["doc.title", "doc.location", "like"])
    +#set ($docTitleDisplayName = $escapetool.xml($services.localization.render('like.livetable.column.title')))
    +#set ($docLocationDisplayName = $escapetool.xml($services.localization.render('like.livetable.column.location')))
    +#set ($likesDisplayName = $escapetool.xml($services.localization.render('like.livetable.column.likes')))
    +#set($columnsProperties = {
    +  "doc.title" : { "displayName": $docTitleDisplayName, "type": "text", "size": 30, "link": "view", "sortable": false, "filterable": false },
    +  "doc.location" : { "displayName": $docLocationDisplayName, "type": "text", "size": 30, "html": true, "sortable": false, "filterable": false },
    +  "like" : { "displayName": $likesDisplayName, "type" : "number", "sortable": false, "filterable": false }
    +})
    +
    +#set ($currentUser = $services.model.serialize($doc.documentReference, "default"))
    +#set ($pageToCallReference = $services.model.resolveDocument("XWiki.Like.UserProfileUIX"))
    +#set ($pageToCall = $xwiki.getDocument($pageToCallReference))
    +#set ($queryParams = {
    +  "user": $currentUser,
    +  "livetable": "true",
    +  "xpage": "plain",
    +  "outputSyntax": "plain"
    +})
    +#set($options = {
    +  'url': $pageToCall.getURL('get', $escapetool.url($queryParams))
    +})
    +#livetable("likedPages" $columns $columnsProperties $options)
     {{/velocity}}</content>
         </property>
         <property>
    

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

7

News mentions

0

No linked articles in our index yet.