CVE-2026-49976 Overview
CVE-2026-49976 is an authorization bypass vulnerability in Snipe-IT, an open-source IT asset and license management system. Versions prior to 8.6.1 allow a user holding only the import permission to abuse CSV update mode to overwrite the email address of any non-admin user. After changing the email, the attacker triggers a password reset and takes over the target account.
The root cause is a broken authorization check [CWE-863] between UserImporter.php and ItemImporter.php. The fix ships in Snipe-IT version 8.6.1.
Critical Impact
A low-privileged user with only import rights can hijack non-admin accounts and pivot laterally within the asset management system.
Affected Products
- Snipe-IT versions prior to 8.6.1
- grokability/snipe-it (all installations exposing the import feature)
- Self-hosted and containerized Snipe-IT deployments
Discovery Timeline
- 2026-08-19 - CVE-2026-49976 published to NVD
- 2026-08-19 - GitHub Security Advisory GHSA-p68w-rgmg-3c2v published alongside Snipe-IT v8.6.1
- 2026-08-19 - Last updated in NVD database
Technical Details for CVE-2026-49976
Vulnerability Analysis
Snipe-IT supports CSV-based user imports, including an update mode that modifies existing user records. The importer contains a gate named canEditAuthFields intended to prevent low-privileged importers from changing sensitive attributes such as username, email, password, and activated.
In app/Importer/UserImporter.php, when the gate denies access, the code calls unset() on those fields of the $user model object. However, the update pipeline does not persist directly from that model. Instead, app/Importer/ItemImporter.php::sanitizeItemForUpdating() rebuilds the update array from the raw CSV row stored in $this->item. Because $this->item was never sanitized, the previously stripped values are reintroduced and written to the database.
The import route in app/Http/Controllers/ImportController.php compounds the issue. It requires only the import permission and does not enforce the stronger users.edit permission, so any user with import rights reaches the vulnerable code path.
Root Cause
The authorization check operates on the wrong data structure. Sanitization removes fields from the Eloquent model, while the persistence step reads them from the raw request payload. This state desynchronization allows unauthorized modification of authentication-relevant fields.
Attack Vector
An authenticated user with the import permission uploads a CSV containing a target user's identifier and a controlled email address. The importer updates the target account with the attacker's email. The attacker then requests a password reset, receives the token at their address, and assumes control of the target account.
// Snipe-IT patch in app/Importer/UserImporter.php (v8.6.1)
$this->log('Updating User');
-if (Auth::check() && (! Gate::allows('canEditAuthFields', $user))) {
- unset($user->username);
- unset($user->email);
- unset($user->password);
- unset($user->activated);
+// CLI imports run unauthenticated and are fully trusted; only restrict web-initiated imports.
+// Note: unset must target $this->item, not the model — sanitizeItemForUpdating() reads from $this->item.
+if (Auth::check() && (! Auth::user()->hasAccess('users.edit') || ! Gate::allows('canEditAuthFields', $user))) {
+ unset($this->item['username']);
+ unset($this->item['email']);
+ unset($this->item['password']);
+ unset($this->item['activated']);
}
$user->update($this->sanitizeItemForUpdating($user));
Source: GitHub Commit dd4117b
Detection Methods for CVE-2026-49976
Indicators of Compromise
- Unexpected user records in the users table where the email column changed shortly before a password reset request for the same account.
- Snipe-IT audit log entries showing a CSV import job followed by password reset activity within a short interval.
- Import jobs submitted by accounts that hold only the import permission and not users.edit.
Detection Strategies
- Review Laravel application logs for POST requests to the /importer/process/{id} route executed by non-admin principals.
- Alert on any modification to users.email originating from an import job rather than the profile editor.
- Correlate password reset token issuance with recent email address changes on the same account.
Monitoring Recommendations
- Enable and centralize Snipe-IT audit logs and forward them to a SIEM for correlation.
- Monitor privileged role assignments and track which accounts hold the import permission.
- Baseline normal import volumes and flag off-hours or first-time importer activity for review.
How to Mitigate CVE-2026-49976
Immediate Actions Required
- Upgrade Snipe-IT to version 8.6.1 or later, which contains the authorization fix.
- Audit which users currently hold the import permission and remove it from accounts that do not require it.
- Review recent user record changes and password reset events for signs of exploitation.
Patch Information
The fix is available in Snipe-IT release v8.6.1. Technical details are documented in GHSA-p68w-rgmg-3c2v and the corresponding Pull Request #19072. The patch adds a users.edit permission check and moves the unset() calls to $this->item so that sanitizeItemForUpdating() cannot restore the stripped fields.
Workarounds
- Temporarily revoke the import permission from all non-administrator accounts until the upgrade is complete.
- Restrict network access to the /importer endpoints via reverse proxy or web application firewall rules.
- Require administrator review of any CSV update job that targets existing user records.
# Verify installed Snipe-IT version and pull the fixed release
cd /var/www/snipe-it
php artisan --version
git fetch --tags
git checkout v8.6.1
composer install --no-dev --prefer-source
php artisan migrate --force
php artisan config:clear && php artisan cache:clear
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

