admidio/admidio: RSS weblinks feed (rss/links.php) leaks role-restricted category links to unauthenticated users
What fixes it
No source in this snapshot names a fixed version.
Description
Summary
rss/links.php builds the weblinks RSS feed with a hand-written query that omits the per-category role-visibility filter used by the HTML view. An unauthenticated visitor (default weblinks_module_enabled=1 public + enable_rss=1) receives links from LNK categories that an administrator restricted via category_view roles.
Root Cause
The HTML weblinks view routes through ModuleWeblinks::getDataSet() which constrains the query to cat_id IN (getAllVisibleCategories('LNK')) (system/classes/ModuleWeblinks.php:118,126). getAllVisibleCategories('LNK') (src/Users/Entity/User.php) excludes any LNK category with a category_view role restriction the current user (a guest holds only role 0) is not a member of. rss/links.php (lines 72-81) re-implements the data query by hand as WHERE cat_type='LNK' AND cat_org_id = ? with no cat_id IN (visible) clause and never calls getAllVisibleCategories, so it emits every LNK category's links including role-restricted ones.
Impact
Anonymous disclosure of link name / URL / description / category / creator-name from categories the administrator restricted to a role. Also affects logged-in non-member users under module mode 2. Confidentiality-only (C:L); no integrity/availability impact.
Proof of Concept
GET /rss/links.php?organization=<shortname>
with no session, when an admin has created a role-restricted LNK category containing private links. The feed returns those restricted links.
Attack Chain
- Entry: Admin creates an LNK category restricted to a members-only role via
category_viewand puts private links in it. Guard: HTMLmodules/links/links.php->getDataSet()->cat_id IN (getAllVisibleCategories('LNK')). Bypass proof: thecategory_viewSQL inUser.phpreturns a restricted category only when the user's role IDs intersect itscategory_viewrows OR the category has no restriction; a guest (roles =[0]) gets neither, so the restricted category is excluded from the HTML view. - Action: Unauthenticated
GET /rss/links.php?organization=<shortname>. Guard:rss/links.php:33-37throws on mode 0 and on (mode 2 && !login). Bypass proof: default mode is1(install/db_scripts/preferences.phpweblinks_module_enabled => '1'), which matches neither throw branch;enable_rss=1by default. Guest passes. - Sink: server runs the query at
rss/links.php:71-81. Guard: NONE. Bypass proof: the WHERE clause is literallycat_type = 'LNK' AND cat_org_id = ?; there is nocat_id IN (...)andgetAllVisibleCategoriesis never called on this path (zero references inrss/links.php). Role-restricted categories are returned. - Impact: anonymous disclosure of role-restricted weblink data.
Bypass Evidence
rss/links.phpquery (lines 71-81):WHERE cat_type = 'LNK' AND cat_org_id = ?โ no visibility filter.- HTML path
ModuleWeblinks.php:118,126usescat_id IN (getAllVisibleCategories('LNK')). - Defaults (
install/db_scripts/preferences.php):enable_rss=1,weblinks_module_enabled=1.
Affected Versions
<= 5.0.14 (latest release). Unfiltered LNK query present since v5.0.0 through latest release; 5.1-beta also affected.
Distinction from prior advisory
Distinct from GHSA-mg9h-42f8-2pmm, which covers the RSS module login gate (mode 2 && !login) on rss/forum.php/rss/announcements.php and explicitly lists rss/links.php as secure w.r.t. that gate. This finding is the per-category role-visibility guard โ a different check.
Suggested Fix
Constrain the rss/links.php query to cat_id IN ($gCurrentUser->getAllVisibleCategories('LNK')), mirroring ModuleWeblinks::getDataSet().
--- Reported by zx (Jace) โ GitHub: @manus-use
Text from GitHub Advisory Database
Affected versions 1
- admidio/admidio, other<= 5.0.15GitHub