CVE-2026-86740 Overview
CVE-2026-86740 affects Snipe-IT asset management software before version 8.7.0. The vulnerability resides in UploadedFilesController::destroy() and Api\UploadedFilesController::destroy(), which fail to check the return value of Storage::delete(). Administrators deleting attachments receive success responses, and the files disappear from listings. However, the physical files persist on disk. Anyone with filesystem or backup access can still retrieve the supposedly deleted content. The flaw maps to [CWE-212: Improper Removal of Sensitive Information Before Storage or Transfer].
Critical Impact
Deleted attachments remain accessible on disk despite success confirmations, exposing sensitive asset documentation to anyone with filesystem or backup access.
Affected Products
- Snipe-IT versions prior to 8.7.0
- Deployments using local or network filesystem storage backends
- Backup archives containing Snipe-IT upload directories
Discovery Timeline
- 2026-09-09 - CVE-2026-86740 published to NVD
- 2026-09-09 - Last updated in NVD database
Technical Details for CVE-2026-86740
Vulnerability Analysis
Snipe-IT's attachment deletion workflow calls Laravel's Storage::delete() method to remove uploaded files from disk. The method returns a boolean indicating whether the deletion succeeded. Both UploadedFilesController::destroy() and its API counterpart discard this return value. The controllers then remove the database record and return a success response regardless of the actual disk operation outcome.
When the underlying storage call fails, due to permission errors, missing files, locked handles, or filesystem faults, the application still reports success. The user interface hides the attachment from listings because the database entry is gone. The physical file remains on disk unchanged.
This inconsistency creates a persistent information disclosure condition. Administrators believe sensitive attachments have been purged. Anyone with shell access, backup access, or read permissions on the upload directory retains the ability to view the original content.
Root Cause
The root cause is missing error handling on the return value of Storage::delete() in the two controller methods. The code assumes deletion always succeeds and provides no reconciliation between the database state and the filesystem state.
Attack Vector
Exploitation requires high privileges since only authenticated users with delete permissions can trigger the flawed code path. The disclosure impact materializes when a secondary actor, such as a backup operator, system administrator, or attacker with filesystem access, reads the residual files. See the GitHub Security Advisory GHSA-4c4h-cpgf-h4qr and the VulnCheck Snipe-IT Advisory for further technical context.
Detection Methods for CVE-2026-86740
Indicators of Compromise
- Files present in the Snipe-IT storage/private_uploads/ directory that have no corresponding row in the uploads or attachment tables
- Attachment records deleted from the Snipe-IT database while identically named files persist on the underlying storage volume
- Backup archives containing attachment files that no longer appear in the running application inventory
Detection Strategies
- Run periodic reconciliation scripts comparing filenames on disk against active database attachment records to surface orphaned files
- Audit application logs for successful DELETE /api/v1/hardware/{id}/files/{fileid} requests and correlate against filesystem state
- Review filesystem access control lists on Snipe-IT upload directories to identify accounts capable of reading residual data
Monitoring Recommendations
- Instrument the Snipe-IT host to log filesystem writes and deletions in the upload directory and forward events to a centralized log platform
- Alert on growth of the upload directory that outpaces new attachment record creation in the database
- Monitor privileged account activity on backup servers that store Snipe-IT data volumes
How to Mitigate CVE-2026-86740
Immediate Actions Required
- Upgrade all Snipe-IT instances to version 8.7.0 or later, which validates the Storage::delete() return value
- Perform a one-time reconciliation between the attachments database table and the upload directory, then manually remove orphaned files
- Rotate or purge backup snapshots that may contain attachments users believed were deleted
- Restrict filesystem and backup access to the smallest set of operators required to run the platform
Patch Information
The issue is fixed in Snipe-IT 8.7.0. The patched controllers now check the boolean returned by Storage::delete() and surface a failure to the caller when the disk operation does not succeed. Refer to the GitHub Security Advisory GHSA-4c4h-cpgf-h4qr for release details.
Workarounds
- Schedule an out-of-band cleanup job that removes files in storage/private_uploads/ with no matching database record
- Limit administrative delete permissions to a small set of trusted accounts until the upgrade is applied
- Encrypt attachment storage at rest and restrict backup retrieval to reduce the exposure window for residual files
# Example reconciliation approach (adapt paths to your deployment)
cd /var/www/snipe-it
php artisan tinker --execute="\\App\\Models\\Actionlog::where('action_type','uploaded')->pluck('filename');"
# Compare the returned list against files present on disk
ls storage/private_uploads/
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

