XWiki Solr script service doesn't take dropped programming right into account
Description
XWiki is a generic wiki platform. In versions starting from 4.5.1 to before 15.10.13, from 16.0.0-rc-1 to before 16.4.4, and from 16.5.0-rc-1 to before 16.8.0-rc-1, the Solr script service doesn't take dropped programming rights into account. The Solr script service that is accessible in XWiki's scripting API normally requires programming rights to be called. Due to using the wrong API for checking rights, it doesn't take the fact into account that programming rights might have been dropped by calling $xcontext.dropPermissions(). If some code relies on this for the safety of executing Velocity code with the wrong author context, this could allow a user with script rights to either cause a high load by indexing documents or to temporarily remove documents from the search index. This issue has been patched in versions 15.10.13, 16.4.4, and 16.8.0-rc-1.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.xwiki.platform:xwiki-platform-search-solr-apiMaven | >= 4.5.1, < 15.10.13 | 15.10.13 |
org.xwiki.platform:xwiki-platform-search-solr-apiMaven | >= 16.0.0-rc-1, < 16.4.4 | 16.4.4 |
org.xwiki.platform:xwiki-platform-search-solr-apiMaven | >= 16.5.0-rc-1, < 16.8.0-rc-1 | 16.8.0-rc-1 |
Affected products
1- Range: >= 4.5.1, < 15.10.13
Patches
16570f40f976aXWIKI-22474: Use the ContextualAuthorization manager in SolrIndexScriptService
2 files changed · +19 −14
xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-solr/xwiki-platform-search-solr-api/src/main/java/org/xwiki/search/solr/script/SolrIndexScriptService.java+5 −1 modified@@ -41,6 +41,7 @@ import org.xwiki.search.solr.internal.api.SolrIndexer; import org.xwiki.security.authorization.AccessDeniedException; import org.xwiki.security.authorization.AuthorizationManager; +import org.xwiki.security.authorization.ContextualAuthorizationManager; import org.xwiki.security.authorization.Right; import com.xpn.xwiki.XWikiContext; @@ -80,6 +81,9 @@ public class SolrIndexScriptService implements ScriptService @Inject private AuthorizationManager authorization; + @Inject + private ContextualAuthorizationManager contextualAuthorizationManager; + /** * Used to access the current {@link XWikiContext}. */ @@ -298,7 +302,7 @@ private void checkAccessToWikiIndex(EntityReference reference) throws AccessDeni XWikiContext xcontext = this.xcontextProvider.get(); this.authorization.checkAccess(Right.ADMIN, xcontext.getUserReference(), wikiReference); - this.authorization.checkAccess(Right.PROGRAM, xcontext.getAuthorReference(), null); + this.contextualAuthorizationManager.checkAccess(Right.PROGRAM); } /**
xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-solr/xwiki-platform-search-solr-api/src/test/java/org/xwiki/search/solr/script/SolrIndexScriptServiceTest.java+14 −13 modified@@ -38,6 +38,7 @@ import org.xwiki.search.solr.internal.reference.SolrEntityReferenceResolver; import org.xwiki.security.authorization.AccessDeniedException; import org.xwiki.security.authorization.AuthorizationManager; +import org.xwiki.security.authorization.ContextualAuthorizationManager; import org.xwiki.security.authorization.Right; import org.xwiki.test.mockito.MockitoComponentMockingRule; @@ -76,14 +77,14 @@ public class SolrIndexScriptServiceTest private DocumentReference userReference; - private DocumentReference contentAuthorReference; - private SolrIndexScriptService service; private Logger logger; private AuthorizationManager mockAuthorization; + private ContextualAuthorizationManager contextualAuthorizationManager; + @Before public void setUp() throws Exception { @@ -106,6 +107,7 @@ public void setUp() throws Exception // RightService this.mockAuthorization = this.mocker.getInstance(AuthorizationManager.class); + this.contextualAuthorizationManager = this.mocker.getInstance(ContextualAuthorizationManager.class); this.service = mocker.getComponentUnderTest(); @@ -126,7 +128,7 @@ public void indexSingleReferenceChecksRights() throws Exception // Actual rights check verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); - verify(this.mockAuthorization).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); } @Test @@ -144,7 +146,7 @@ public void indexMultipleReferencesChecksRights() throws Exception // Actual rights check verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); - verify(this.mockAuthorization).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); } @Test @@ -159,7 +161,7 @@ public void deleteSingleReferenceChecksRights() throws Exception // Actual rights check verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); - verify(this.mockAuthorization).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); } @Test @@ -177,7 +179,7 @@ public void deleteMultipleReferencesChecksRights() throws Exception // Actual rights check verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); - verify(this.mockAuthorization).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); } @Test @@ -193,7 +195,7 @@ public void operationsChecksRightsWithOtherReferences() throws Exception // Actual rights check EntityReference wikiReference = documentReference.extractReference(EntityType.WIKI); verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); - verify(this.mockAuthorization).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); } @Test @@ -202,8 +204,7 @@ public void hasWikiAdminButNoProgrammingCausesRightsCheckFailure() throws Except EntityReference wikiReference = new WikiReference("someWiki"); // Mock - doThrow(AccessDeniedException.class).when(this.mockAuthorization).checkAccess(Right.PROGRAM, - this.contentAuthorReference, null); + doThrow(AccessDeniedException.class).when(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); // Call this.service.index(wikiReference); @@ -212,7 +213,7 @@ public void hasWikiAdminButNoProgrammingCausesRightsCheckFailure() throws Except // Actual rights check verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); - verify(this.mockAuthorization).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); // Rights check failure verify(this.logger).error(isNull(), any(AccessDeniedException.class)); @@ -237,7 +238,7 @@ public void hasProgrammingButNoWikiAdminCausesRightsCheckFailure() throws Except // Actual rights check verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); // hasProgrammingRights does not really get to be called, since hasWikiAdminRights already failed at this point - verify(this.mockAuthorization, times(0)).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager, times(0)).checkAccess(Right.PROGRAM); // Rights check failure. verify(this.logger).error(isNull(), any(AccessDeniedException.class)); @@ -262,7 +263,7 @@ public void openrationsOnMultipleReferencesOnTheSameWikiChecksRightsOnlyOnceForT // Actual rights check verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference); - verify(this.mockAuthorization).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager).checkAccess(Right.PROGRAM); } @Test @@ -286,7 +287,7 @@ public void openrationsOnMultipleReferencesOnDifferentWikisChecksRightsOnEachWik verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference1); verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference2); verify(this.mockAuthorization).checkAccess(Right.ADMIN, this.userReference, wikiReference3); - verify(this.mockAuthorization, times(3)).checkAccess(Right.PROGRAM, this.contentAuthorReference, null); + verify(this.contextualAuthorizationManager, times(3)).checkAccess(Right.PROGRAM); } @Test
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- github.com/advisories/GHSA-987p-r3jc-8c8vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-32971ghsaADVISORY
- github.com/xwiki/xwiki-platform/commit/6570f40f976aec82baf388b5239d1412cab238c9ghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-platform/security/advisories/GHSA-987p-r3jc-8c8vghsax_refsource_CONFIRMWEB
- jira.xwiki.org/browse/XWIKI-22474ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.