VYPR
Low severityNVD Advisory· Published Apr 30, 2025· Updated Apr 30, 2025

The lesscss script service allows cache clearing without programming right

CVE-2025-32972

Description

XWiki is a generic wiki platform. In versions starting from 6.1-milestone-1 to before 15.10.12, from 16.0.0-rc-1 to before 16.4.3, and from 16.5.0-rc-1 to before 16.8.0-rc-1, the script API of the LESS compiler in XWiki is incorrectly checking for rights when calling the cache cleaning API, making it possible to clean the cache without having programming right. The only impact of this is a slowdown in XWiki execution as the caches are re-filled. As this vulnerability requires script right to exploit, and script right already allows unlimited execution of scripts, the additional impact due to this vulnerability is low. This issue has been patched in versions 15.10.12, 16.4.3, and 16.8.0-rc-1.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-lesscss-scriptMaven
>= 6.1-milestone-1, < 15.10.1215.10.12
org.xwiki.platform:xwiki-platform-lesscss-scriptMaven
>= 16.0.0-rc-1, < 16.4.316.4.3
org.xwiki.platform:xwiki-platform-lesscss-scriptMaven
>= 16.5.0-rc-1, < 16.8.0-rc-116.8.0-rc-1

Affected products

1

Patches

1
91752122d878

XWIKI-22462: Use the contextual authorization manager in the lesscss script service

https://github.com/xwiki/xwiki-platformMichael HamannAug 29, 2024via ghsa
2 files changed · +41 29
  • xwiki-platform-core/xwiki-platform-lesscss/xwiki-platform-lesscss-script/src/main/java/org/xwiki/lesscss/LessCompilerScriptService.java+5 20 modified
    @@ -21,7 +21,6 @@
     
     import javax.inject.Inject;
     import javax.inject.Named;
    -import javax.inject.Provider;
     import javax.inject.Singleton;
     
     import org.apache.commons.lang3.exception.ExceptionUtils;
    @@ -38,11 +37,9 @@
     import org.xwiki.lesscss.internal.skin.SkinReferenceFactory;
     import org.xwiki.lesscss.resources.LESSResourceReferenceFactory;
     import org.xwiki.script.service.ScriptService;
    -import org.xwiki.security.authorization.AuthorizationManager;
    +import org.xwiki.security.authorization.ContextualAuthorizationManager;
     import org.xwiki.security.authorization.Right;
     
    -import com.xpn.xwiki.XWikiContext;
    -
     /**
      * This script service provides a LESS preprocessor (http://lesscss.org/) for CSS generation.
      *
    @@ -66,9 +63,6 @@ public class LessCompilerScriptService implements ScriptService
         @Inject
         private ColorThemeCache colorThemeCache;
     
    -    @Inject
    -    private Provider<XWikiContext> xcontextProvider;
    -
         @Inject
         private LESSColorThemeConverter lessColorThemeConverter;
     
    @@ -79,7 +73,7 @@ public class LessCompilerScriptService implements ScriptService
         private ColorThemeReferenceFactory colorThemeReferenceFactory;
     
         @Inject
    -    private AuthorizationManager authorizationManager;
    +    private ContextualAuthorizationManager authorizationManager;
     
         /**
          * Compile a LESS file located in the "less" directory of the current skin directory.
    @@ -184,11 +178,8 @@ public ColorTheme getColorThemeFromSkinFile(String filename, String skin)
          */
         public boolean clearCache()
         {
    -        XWikiContext xcontext = xcontextProvider.get();
    -
             // Check if the current script has the programing rights
    -        if (!authorizationManager.hasAccess(Right.PROGRAM, xcontext.getDoc().getAuthorReference(),
    -            xcontext.getDoc().getDocumentReference())) {
    +        if (!authorizationManager.hasAccess(Right.PROGRAM)) {
                 return false;
             }
     
    @@ -205,11 +196,8 @@ public boolean clearCache()
          */
         public boolean clearCacheFromColorTheme(String colorTheme)
         {
    -        XWikiContext xcontext = xcontextProvider.get();
    -
             // Check if the current script has the programing rights
    -        if (!authorizationManager.hasAccess(Right.PROGRAM, xcontext.getDoc().getAuthorReference(),
    -                xcontext.getDoc().getDocumentReference())) {
    +        if (!authorizationManager.hasAccess(Right.PROGRAM)) {
                 return false;
             }
     
    @@ -233,11 +221,8 @@ public boolean clearCacheFromColorTheme(String colorTheme)
          */
         public boolean clearCacheFromSkin(String skin)
         {
    -        XWikiContext xcontext = xcontextProvider.get();
    -
             // Check if the current script has the programing rights
    -        if (!authorizationManager.hasAccess(Right.PROGRAM, xcontext.getDoc().getAuthorReference(),
    -                xcontext.getDoc().getDocumentReference())) {
    +        if (!authorizationManager.hasAccess(Right.PROGRAM)) {
                 return false;
             }
     
    
  • xwiki-platform-core/xwiki-platform-lesscss/xwiki-platform-lesscss-script/src/test/java/org/xwiki/lesscss/LessCompilerScriptServiceTest.java+36 9 modified
    @@ -37,7 +37,7 @@
     import org.xwiki.lesscss.resources.LESSResourceReference;
     import org.xwiki.lesscss.resources.LESSResourceReferenceFactory;
     import org.xwiki.model.reference.DocumentReference;
    -import org.xwiki.security.authorization.AuthorizationManager;
    +import org.xwiki.security.authorization.ContextualAuthorizationManager;
     import org.xwiki.security.authorization.Right;
     import org.xwiki.test.mockito.MockitoComponentMockingRule;
     
    @@ -74,7 +74,7 @@ public class LessCompilerScriptServiceTest
     
         private LESSColorThemeConverter lessColorThemeConverter;
     
    -    private AuthorizationManager authorizationManager;
    +    private ContextualAuthorizationManager authorizationManager;
     
         private Provider<XWikiContext> xcontextProvider;
     
    @@ -92,7 +92,7 @@ public void setUp() throws Exception
             lessCache = mocker.getInstance(LESSResourcesCache.class);
             lessResourceReferenceFactory = mocker.getInstance(LESSResourceReferenceFactory.class);
             colorThemeCache = mocker.getInstance(ColorThemeCache.class);
    -        authorizationManager = mocker.getInstance(AuthorizationManager.class);
    +        authorizationManager = mocker.getInstance(ContextualAuthorizationManager.class);
             skinReferenceFactory = mocker.getInstance(SkinReferenceFactory.class);
             colorThemeReferenceFactory = mocker.getInstance(ColorThemeReferenceFactory.class);
             xcontextProvider = mocker.registerMockComponent(XWikiContext.TYPE_PROVIDER);
    @@ -247,7 +247,7 @@ public void clearCacheWithRights() throws Exception
             DocumentReference currentDocReference = new DocumentReference("wiki", "Space", "Page");
             when(doc.getDocumentReference()).thenReturn(currentDocReference);
     
    -        when(authorizationManager.hasAccess(Right.PROGRAM, authorReference, currentDocReference)).thenReturn(true);
    +        when(authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(true);
     
             // Tests
             assertTrue(mocker.getComponentUnderTest().clearCache());
    @@ -268,7 +268,7 @@ public void clearCacheWithoutRights() throws Exception
             DocumentReference currentDocReference = new DocumentReference("wiki", "Space", "Page");
             when(doc.getDocumentReference()).thenReturn(currentDocReference);
     
    -        when(authorizationManager.hasAccess(Right.PROGRAM, authorReference, currentDocReference)).thenReturn(false);
    +        when(authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(false);
     
             // Tests
             assertFalse(mocker.getComponentUnderTest().clearCache());
    @@ -289,7 +289,7 @@ public void clearCacheFromColorThemeWithRights() throws Exception
             DocumentReference currentDocReference = new DocumentReference("wiki", "Space", "Page");
             when(doc.getDocumentReference()).thenReturn(currentDocReference);
     
    -        when(authorizationManager.hasAccess(Right.PROGRAM, authorReference, currentDocReference)).thenReturn(true);
    +        when(authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(true);
     
             ColorThemeReference colorThemeReference = mock(ColorThemeReference.class);
             when(colorThemeReferenceFactory.createReference("colorTheme")).thenReturn(colorThemeReference);
    @@ -313,7 +313,7 @@ public void clearCacheFromColorThemeWithoutRights() throws Exception
             DocumentReference currentDocReference = new DocumentReference("wiki", "Space", "Page");
             when(doc.getDocumentReference()).thenReturn(currentDocReference);
     
    -        when(authorizationManager.hasAccess(Right.PROGRAM, authorReference, currentDocReference)).thenReturn(false);
    +        when(authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(false);
     
             // Tests
             assertFalse(mocker.getComponentUnderTest().clearCacheFromColorTheme("colorTheme"));
    @@ -323,6 +323,20 @@ public void clearCacheFromColorThemeWithoutRights() throws Exception
             verifyNoInteractions(colorThemeCache);
         }
     
    +    @Test
    +    public void clearCacheFromColorThemeWithException() throws Exception
    +    {
    +        when(this.authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(true);
    +
    +        LESSCompilerException lessCompilerException = new LESSCompilerException("Test Exception");
    +        when(this.colorThemeReferenceFactory.createReference("colorTheme")).thenThrow(lessCompilerException);
    +
    +        assertFalse(mocker.getComponentUnderTest().clearCacheFromColorTheme("colorTheme"));
    +
    +        verifyNoInteractions(lessCache);
    +        verifyNoInteractions(colorThemeCache);
    +    }
    +
         @Test
         public void clearCacheFromSkinWithRights() throws Exception
         {
    @@ -334,7 +348,7 @@ public void clearCacheFromSkinWithRights() throws Exception
             DocumentReference currentDocReference = new DocumentReference("wiki", "Space", "Page");
             when(doc.getDocumentReference()).thenReturn(currentDocReference);
     
    -        when(authorizationManager.hasAccess(Right.PROGRAM, authorReference, currentDocReference)).thenReturn(true);
    +        when(authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(true);
     
             SkinReference skinReference = mock(SkinReference.class);
             when(skinReferenceFactory.createReference("skin")).thenReturn(skinReference);
    @@ -358,7 +372,7 @@ public void clearCacheFromSkinWithoutRights() throws Exception
             DocumentReference currentDocReference = new DocumentReference("wiki", "Space", "Page");
             when(doc.getDocumentReference()).thenReturn(currentDocReference);
     
    -        when(authorizationManager.hasAccess(Right.PROGRAM, authorReference, currentDocReference)).thenReturn(false);
    +        when(authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(false);
     
             // Tests
             assertFalse(mocker.getComponentUnderTest().clearCacheFromSkin("skin"));
    @@ -368,4 +382,17 @@ public void clearCacheFromSkinWithoutRights() throws Exception
             verifyNoInteractions(colorThemeCache);
         }
     
    +    @Test
    +    public void clearCacheFromSkinWithException() throws Exception
    +    {
    +        when(this.authorizationManager.hasAccess(Right.PROGRAM)).thenReturn(true);
    +
    +        LESSCompilerException exception = new LESSCompilerException("test");
    +        when(skinReferenceFactory.createReference("skin")).thenThrow(exception);
    +
    +        assertFalse(this.mocker.getComponentUnderTest().clearCacheFromSkin("skin"));
    +
    +        verifyNoInteractions(this.lessCache);
    +        verifyNoInteractions(this.colorThemeCache);
    +    }
     }
    

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

5

News mentions

0

No linked articles in our index yet.