Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Single network PATCH request (AV:N/AC:L/UI:N) but requires an authenticated users.edit account (PR:L); self-escalation to admin yields full C/I/A impact within the same application scope (S:U).
Primary rating from Vendor (https://github.com/grokability/snipe-it).
CVSS VectorVendor: https://github.com/grokability/snipe-it
Lifecycle Timeline
6DescriptionCVE.org
Impact
An authenticated user with only users.edit permission can escalate their own privileges to admin by sending a PATCH request to /api/v1/users/{id} with permissions[admin]=1. The API controller only strips the superuser key from the permissions array, allowing admin and all other permission keys to be set by any user who can update users.
Patches
Patched in https://github.com/grokability/snipe-it/commit/ce18ff669ceb0f0349749fd5d11c1d3d40b10569, fix was released in v8.4.1
Workarounds
None.
AnalysisAI
Privilege escalation in Snipe-IT versions before 8.4.1 allows an authenticated user holding only the users.edit permission to grant themselves the admin role by sending a PATCH request to /api/v1/users/{id} with permissions[admin]=1. The API user controller sanitized only the superuser key from the submitted permissions array, leaving admin and every other permission assignable by any account able to edit users. No public exploit has been identified at time of analysis and the EPSS score is very low (0.01%), but the trivial exploit primitive and full admin takeover make this a high-severity issue (vendor CVSS 4.0 8.7).
Technical ContextAI
Snipe-IT is a Laravel (PHP) open-source IT asset management application distributed via Composer as snipe/snipe-it. Permissions are stored per user as a JSON-encoded array of permission keys. The flaw is a CWE-281 (Improper Preservation of Permissions) mass-assignment gap: in the API UsersController, the code stripped only the superuser key from the incoming permissions array before persisting it, implicitly trusting all remaining keys - including the powerful admin key. Because the web/API layer never re-checked whether the acting user was itself an admin/superuser before allowing admin to be set, any principal with the lower users.edit capability could write a higher-privilege flag. The patch (commit ce18ff6, v8.4.1) both properly JSON-encodes the permissions in the API store path and, in the web update path, captures the original admin value and forces it back unless the acting user is already an admin or superuser (if ((! auth()->user()->isSuperUser()) && (! auth()->user()->isAdmin())) { $permissions_array['admin'] = $orig_admin; }).
RemediationAI
Vendor-released patch: upgrade to Snipe-IT v8.4.1 or later, which includes commit ce18ff669ceb0f0349749fd5d11c1d3d40b10569 that forces the original admin value unless the acting user is already an admin or superuser and properly JSON-encodes the API permissions payload. The vendor states there are no workarounds, so patching is the only complete fix. As interim compensating controls until you can upgrade, treat the users.edit permission as admin-equivalent and revoke it from any non-trusted account, audit existing users for unexpected admin flags (an attacker may have already self-escalated), and restrict or monitor access to the /api/v1/users/{id} PATCH endpoint (e.g., via WAF rules alerting on request bodies containing permissions[admin]); note these controls reduce but do not eliminate exposure and may impede legitimate delegated user administration. Refer to the advisory at https://github.com/grokability/snipe-it/security/advisories/GHSA-hq28-crg7-95pr and the patch commit for details.
Same weakness CWE-281 – Improper Preservation of Permissions
View allSame technique Privilege Escalation
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-31962
GHSA-hq28-crg7-95pr