Data leak of notification filters of users in XWiki Platform
Description
XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. It's possible to get access to notification filters of any user by using a URL such as <hostname>xwiki/bin/get/XWiki/Notifications/Code/NotificationFilterPreferenceLivetableResults?outputSyntax=plain&type=custom&user=<username>. This vulnerability impacts all versions of XWiki since 13.2-rc-1. The filters do not provide much information (they mainly contain references which are public data in XWiki), though some info could be used in combination with other vulnerabilities. This vulnerability has been patched in XWiki 14.10.21, 15.5.5, 15.10.1, 16.0RC1. The patch consists in checking the rights of the user when sending the data. Users are advised to upgrade. It's possible to workaround the vulnerability by applying manually the patch: it's possible for an administrator to edit directly the document XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults to apply the same changes as in the patch. See commit c8c6545f9bde6f5aade994aa5b5903a67b5c2582.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.xwiki.platform:xwiki-platform-notifications-uiMaven | >= 13.2-rc-1, < 14.10.21 | 14.10.21 |
org.xwiki.platform:xwiki-platform-notifications-uiMaven | >= 15.0-rc-1, < 15.5.5 | 15.5.5 |
org.xwiki.platform:xwiki-platform-notifications-uiMaven | >= 15.6-rc-1, < 15.10.1 | 15.10.1 |
Affected products
1- Range: >= 13.2-rc-1, < 14.10.21
Patches
4c8c6545f9bdeXWIKI-20336: Wrong results in NotificationFilterPreferenceLivetableResults
1 file changed · +27 −19
xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-ui/src/main/resources/XWiki/Notifications/Code/NotificationFilterPreferenceLivetableResults.xml+27 −19 modified@@ -20,7 +20,7 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> -<xwikidoc version="1.4" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> +<xwikidoc version="1.5" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> <web>XWiki.Notifications.Code</web> <name>NotificationFilterPreferenceLivetableResults</name> <language/> @@ -55,15 +55,19 @@ ## ## Build the list of NotificationFilterPreference related to the given user. ## +#set ($isAccessGranted = false) #if ("$!request.user" != "") - #set ($document = $xwiki.getDocument($services.model.resolveDocument($request.user))) + #set ($requestedUserDocRef = $services.model.resolveDocument($request.user)) + #set ($isAccessGranted = ($services.security.authorization.hasAccess('admin', $requestedUserDocRef) || $xcontext.userReference.equals($requestedUserDocRef))) + #set ($document = $xwiki.getDocument($requestedUserDocRef)) #set ($target = $request.user) #set ($userTarget = true) ## when request user is not given we are sending the list of NotificationFilterPreference of the current wiki. #else #set ($target = $services.wiki.getCurrentWikiReference()) #set ($document = $xwiki.getDocument('XWiki.Notifications.Code.NotificationAdministration')) #set ($userTarget = false) + #set ($isAccessGranted = true) #end #set ($elements = []) #set ($index = 0) @@ -82,7 +86,7 @@ #set ($displayCustom = false) #end -#if ($displaySystem) +#if ($displaySystem && $isAccessGranted) ## First: get the list of available toggeable filters for the user ## We display them first because we don't want them to be hidden by thousands of page filters the autowatch option ## might have created. It would be not good to have to go to the last page of the livetable to find out these commonly @@ -126,7 +130,7 @@ #set ($elements = $collectiontool.sort($elements, ['name'])) #end -#if ($displayCustom) +#if ($displayCustom && $isAccessGranted) ## Also get the list of available filters for the user #set ($filters = $collectiontool.arrayList) #if ($userTarget) @@ -188,22 +192,26 @@ #end #end #end -## -## JSON. -## -#set ($discard = $response.setContentType('application/json')) -#set ($offset = $numbertool.toNumber($request.offset)) -#if (!$offset) - #set ($offset = 1) -#end -$jsontool.serialize({ - 'totalrows' : $index, - 'reqNo' : $request.reqNo, - 'returnedrows': $elements.size(), - 'offset' : $offset, - 'rows' : $elements -}) +#if ($isAccessGranted) + ## + ## JSON. + ## + #set ($discard = $response.setContentType('application/json')) + #set ($offset = $numbertool.toNumber($request.offset)) + #if (!$offset) + #set ($offset = 1) + #end + $jsontool.serialize({ + 'totalrows' : $index, + 'reqNo' : $request.reqNo, + 'returnedrows': $elements.size(), + 'offset' : $offset, + 'rows' : $elements + }) +#else + #set ($discard = $response.sendError(401)) #end +#end ## (context action) ## ## MACROS ##
29e5edbb2b70XWIKI-20336: Wrong results in NotificationFilterPreferenceLivetableResults
1 file changed · +27 −19
xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-ui/src/main/resources/XWiki/Notifications/Code/NotificationFilterPreferenceLivetableResults.xml+27 −19 modified@@ -20,7 +20,7 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> -<xwikidoc version="1.4" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> +<xwikidoc version="1.5" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> <web>XWiki.Notifications.Code</web> <name>NotificationFilterPreferenceLivetableResults</name> <language/> @@ -55,15 +55,19 @@ ## ## Build the list of NotificationFilterPreference related to the given user. ## +#set ($isAccessGranted = false) #if ("$!request.user" != "") - #set ($document = $xwiki.getDocument($services.model.resolveDocument($request.user))) + #set ($requestedUserDocRef = $services.model.resolveDocument($request.user)) + #set ($isAccessGranted = ($services.security.authorization.hasAccess('admin', $requestedUserDocRef) || $xcontext.userReference.equals($requestedUserDocRef))) + #set ($document = $xwiki.getDocument($requestedUserDocRef)) #set ($target = $request.user) #set ($userTarget = true) ## when request user is not given we are sending the list of NotificationFilterPreference of the current wiki. #else #set ($target = $services.wiki.getCurrentWikiReference()) #set ($document = $xwiki.getDocument('XWiki.Notifications.Code.NotificationAdministration')) #set ($userTarget = false) + #set ($isAccessGranted = true) #end #set ($elements = []) #set ($index = 0) @@ -82,7 +86,7 @@ #set ($displayCustom = false) #end -#if ($displaySystem) +#if ($displaySystem && $isAccessGranted) ## First: get the list of available toggeable filters for the user ## We display them first because we don't want them to be hidden by thousands of page filters the autowatch option ## might have created. It would be not good to have to go to the last page of the livetable to find out these commonly @@ -126,7 +130,7 @@ #set ($elements = $collectiontool.sort($elements, ['name'])) #end -#if ($displayCustom) +#if ($displayCustom && $isAccessGranted) ## Also get the list of available filters for the user #set ($filters = $collectiontool.arrayList) #if ($userTarget) @@ -188,22 +192,26 @@ #end #end #end -## -## JSON. -## -#set ($discard = $response.setContentType('application/json')) -#set ($offset = $numbertool.toNumber($request.offset)) -#if (!$offset) - #set ($offset = 1) -#end -$jsontool.serialize({ - 'totalrows' : $index, - 'reqNo' : $request.reqNo, - 'returnedrows': $elements.size(), - 'offset' : $offset, - 'rows' : $elements -}) +#if ($isAccessGranted) + ## + ## JSON. + ## + #set ($discard = $response.setContentType('application/json')) + #set ($offset = $numbertool.toNumber($request.offset)) + #if (!$offset) + #set ($offset = 1) + #end + $jsontool.serialize({ + 'totalrows' : $index, + 'reqNo' : $request.reqNo, + 'returnedrows': $elements.size(), + 'offset' : $offset, + 'rows' : $elements + }) +#else + #set ($discard = $response.sendError(401)) #end +#end ## (context action) ## ## MACROS ##
a0352922a1a6XWIKI-20336: Wrong results in NotificationFilterPreferenceLivetableResults
1 file changed · +27 −19
xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-ui/src/main/resources/XWiki/Notifications/Code/NotificationFilterPreferenceLivetableResults.xml+27 −19 modified@@ -20,7 +20,7 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> -<xwikidoc version="1.4" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> +<xwikidoc version="1.5" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> <web>XWiki.Notifications.Code</web> <name>NotificationFilterPreferenceLivetableResults</name> <language/> @@ -55,15 +55,19 @@ ## ## Build the list of NotificationFilterPreference related to the given user. ## +#set ($isAccessGranted = false) #if ("$!request.user" != "") - #set ($document = $xwiki.getDocument($services.model.resolveDocument($request.user))) + #set ($requestedUserDocRef = $services.model.resolveDocument($request.user)) + #set ($isAccessGranted = ($services.security.authorization.hasAccess('admin', $requestedUserDocRef) || $xcontext.userReference.equals($requestedUserDocRef))) + #set ($document = $xwiki.getDocument($requestedUserDocRef)) #set ($target = $request.user) #set ($userTarget = true) ## when request user is not given we are sending the list of NotificationFilterPreference of the current wiki. #else #set ($target = $services.wiki.getCurrentWikiReference()) #set ($document = $xwiki.getDocument('XWiki.Notifications.Code.NotificationAdministration')) #set ($userTarget = false) + #set ($isAccessGranted = true) #end #set ($elements = []) #set ($index = 0) @@ -82,7 +86,7 @@ #set ($displayCustom = false) #end -#if ($displaySystem) +#if ($displaySystem && $isAccessGranted) ## First: get the list of available toggeable filters for the user ## We display them first because we don't want them to be hidden by thousands of page filters the autowatch option ## might have created. It would be not good to have to go to the last page of the livetable to find out these commonly @@ -126,7 +130,7 @@ #set ($elements = $collectiontool.sort($elements, ['name'])) #end -#if ($displayCustom) +#if ($displayCustom && $isAccessGranted) ## Also get the list of available filters for the user #set ($filters = $collectiontool.arrayList) #if ($userTarget) @@ -188,22 +192,26 @@ #end #end #end -## -## JSON. -## -#set ($discard = $response.setContentType('application/json')) -#set ($offset = $numbertool.toNumber($request.offset)) -#if (!$offset) - #set ($offset = 1) -#end -$jsontool.serialize({ - 'totalrows' : $index, - 'reqNo' : $request.reqNo, - 'returnedrows': $elements.size(), - 'offset' : $offset, - 'rows' : $elements -}) +#if ($isAccessGranted) + ## + ## JSON. + ## + #set ($discard = $response.setContentType('application/json')) + #set ($offset = $numbertool.toNumber($request.offset)) + #if (!$offset) + #set ($offset = 1) + #end + $jsontool.serialize({ + 'totalrows' : $index, + 'reqNo' : $request.reqNo, + 'returnedrows': $elements.size(), + 'offset' : $offset, + 'rows' : $elements + }) +#else + #set ($discard = $response.sendError(401)) #end +#end ## (context action) ## ## MACROS ##
ed090d1aa228XWIKI-20336: Wrong results in NotificationFilterPreferenceLivetableResults
1 file changed · +27 −19
xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-ui/src/main/resources/XWiki/Notifications/Code/NotificationFilterPreferenceLivetableResults.xml+27 −19 modified@@ -20,7 +20,7 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> -<xwikidoc version="1.4" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> +<xwikidoc version="1.5" reference="XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults" locale=""> <web>XWiki.Notifications.Code</web> <name>NotificationFilterPreferenceLivetableResults</name> <language/> @@ -55,15 +55,19 @@ ## ## Build the list of NotificationFilterPreference related to the given user. ## +#set ($isAccessGranted = false) #if ("$!request.user" != "") - #set ($document = $xwiki.getDocument($services.model.resolveDocument($request.user))) + #set ($requestedUserDocRef = $services.model.resolveDocument($request.user)) + #set ($isAccessGranted = ($services.security.authorization.hasAccess('admin', $requestedUserDocRef) || $xcontext.userReference.equals($requestedUserDocRef))) + #set ($document = $xwiki.getDocument($requestedUserDocRef)) #set ($target = $request.user) #set ($userTarget = true) ## when request user is not given we are sending the list of NotificationFilterPreference of the current wiki. #else #set ($target = $services.wiki.getCurrentWikiReference()) #set ($document = $xwiki.getDocument('XWiki.Notifications.Code.NotificationAdministration')) #set ($userTarget = false) + #set ($isAccessGranted = true) #end #set ($elements = []) #set ($index = 0) @@ -82,7 +86,7 @@ #set ($displayCustom = false) #end -#if ($displaySystem) +#if ($displaySystem && $isAccessGranted) ## First: get the list of available toggeable filters for the user ## We display them first because we don't want them to be hidden by thousands of page filters the autowatch option ## might have created. It would be not good to have to go to the last page of the livetable to find out these commonly @@ -126,7 +130,7 @@ #set ($elements = $collectiontool.sort($elements, ['name'])) #end -#if ($displayCustom) +#if ($displayCustom && $isAccessGranted) ## Also get the list of available filters for the user #set ($filters = $collectiontool.arrayList) #if ($userTarget) @@ -188,22 +192,26 @@ #end #end #end -## -## JSON. -## -#set ($discard = $response.setContentType('application/json')) -#set ($offset = $numbertool.toNumber($request.offset)) -#if (!$offset) - #set ($offset = 1) -#end -$jsontool.serialize({ - 'totalrows' : $index, - 'reqNo' : $request.reqNo, - 'returnedrows': $elements.size(), - 'offset' : $offset, - 'rows' : $elements -}) +#if ($isAccessGranted) + ## + ## JSON. + ## + #set ($discard = $response.setContentType('application/json')) + #set ($offset = $numbertool.toNumber($request.offset)) + #if (!$offset) + #set ($offset = 1) + #end + $jsontool.serialize({ + 'totalrows' : $index, + 'reqNo' : $request.reqNo, + 'returnedrows': $elements.size(), + 'offset' : $offset, + 'rows' : $elements + }) +#else + #set ($discard = $response.sendError(401)) #end +#end ## (context action) ## ## MACROS ##
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
8- github.com/advisories/GHSA-pg4m-3gp6-hw4wghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-46979ghsaADVISORY
- github.com/xwiki/xwiki-platform/commit/29e5edbb2b7068ada17290cea41e0aa8144e1294ghsaWEB
- github.com/xwiki/xwiki-platform/commit/a0352922a1a61e0e858a9be89d73f0665630a63aghsaWEB
- github.com/xwiki/xwiki-platform/commit/c8c6545f9bde6f5aade994aa5b5903a67b5c2582ghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-platform/commit/ed090d1aa228848d3860968c437b72db3b09119fghsaWEB
- github.com/xwiki/xwiki-platform/security/advisories/GHSA-pg4m-3gp6-hw4wghsax_refsource_CONFIRMWEB
- jira.xwiki.org/browse/XWIKI-20336ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.