fluentcms / fluentcms/FluentCMS

Cross-tenant authorization bypass in PermissionManager and File/Folder services

Open
#2,409 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
565
Forks
107
PR merge metrics
No merged PRs in 30d

Description

### Summary

FluentCMS does not consistently bind authorization decisions to the site that owns the requested object. An authenticated administrator restricted to Site A can enumerate Site B and, when a Site B folder UUID is supplied to File Management, read and modify Site B assets.

Tested on official tag `v0.0.5`. The same vulnerable code is present at `dev` commit `c63d49cdbc1f4051d34bb71087d904c56e33951e`.

### Root cause

In `PermissionManager.HasAccess(Guid siteId, ...)`, authorization collections are populated once and then reused for later site IDs:

```csharp
_userRoles ??= (await _userRoleRepository.GetUserRoles(_apiExecutionContext.UserId, siteId, cancellationToken))
.Where(ur => ur.SiteId == siteId).ToList();
_roles ??= (await _roleRepository.GetAllForSite(siteId, cancellationToken)).ToList();
_permissions ??= (await _permissionRepository.GetAllForSite(siteId, cancellationToken)).ToList();
```

`GetAccessible` calls `HasAccess` repeatedly for different sites, so roles loaded for the first site can be reused when evaluating subsequent sites.

Additionally, `FolderService.GetAll/GetById` and `FileService.Create/GetById` access objects by UUID without checking `IPermissionManager.HasAccess` for the owning `SiteId`.

Affected source:

- https://github.com/fluentcms/FluentCMS/blob/c63d49cdbc1f4051d34bb71087d904c56e33951e/src/Backend/FluentCMS.Services/Permissions/PermissionManager.cs
- https://github.com/fluentcms/FluentCMS/blob/c63d49cdbc1f4051d34bb71087d904c56e33951e/src/Backend/FluentCMS.Services/FolderService.cs
- https://github.com/fluentcms/FluentCMS/blob/c63d49cdbc1f4051d34bb71087d904c56e33951e/src/Backend/FluentCMS.Services/FileService.cs

### Proof of concept

1. Create Site A and Site B.
2. Assign a test account to the `Administrators` role of Site A only. Do not assign any Site B role.
3. Authenticate as that Site A-only administrator.
4. Open `/admin/sites`.
5. Observe that Site B and its ID are returned to the Site A-only administrator.
6. Supply a Site B folder UUID to `/admin/files?folderId=`.
7. Observe that Site B filenames and download paths are rendered.
8. Upload a benign text file through File Management while the Site B folder is selected.
9. Observe that the created object belongs to Site B but its `createdBy` field is the Site A-only administrator.

Laboratory assertions:

```text
GET /admin/files?folderId=
Status: 200
Authenticated as Site A-only administrator: true
Site B filename disclosed: true
Site B download link disclosed: true

Cross-site upload response:
siteId:
folderId:
createdBy:
isSuccess: true
```

### Impact

A site administrator may enumerate sites outside their assigned scope and, with a referenced object UUID, read, upload, rename, move, or delete assets belonging to another site. This violates tenant isolation and can affect confidentiality, integrity, and availability in multi-site deployments.

### Severity

- High
- CVSS 3.1: `CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H` (7.2)
- CWE-862: Missing Authorization
- CWE-639: Authorization Bypass Through User-Controlled Key

### Suggested remediation

- Key cached authorization data by `siteId`, or reload it for every site evaluation.
- Add explicit per-site authorization checks to every File and Folder read/write operation.
- Add two-site integration tests verifying that a Site A administrator cannot enumerate or mutate Site B objects.

I am available to provide additional reproduction details and validate a patch.

Contributor guide

Open the contributing guide

Research direction

Start with PermissionManager.HasAccess and GetAccessible, then inspect FolderService.GetAll/GetById and FileService.Create/GetById at the referenced commit. Trace how site IDs and object UUIDs reach authorization decisions. Done means two-site integration tests show a Site A administrator cannot enumerate or read or mutate Site B folders and files.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
authorization, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.