Aug 20, 2026·7 min read·2 visits
Chained IDOR and information disclosure in Snipe-IT allows authenticated, low-privileged users to bypass file name randomization and download signed EULAs of any user.
CVE-2026-55694 is a chained Information Disclosure and Insecure Direct Object Reference (IDOR) vulnerability in Snipe-IT prior to version 8.6.3. The vulnerability allows authenticated, restricted users to completely bypass randomized file-naming security controls, leak the obfuscated filenames of signed End User License Agreements (EULAs), and subsequently download these confidential documents across tenant boundaries.
Snipe-IT is an open-source, web-based IT asset and license management platform built on the Laravel framework. The application allows enterprises to track physical hardware, software license allocations, and administrative records. A critical component of this asset tracking workflow is the signature and retention of End User License Agreements (EULAs), which serve as legally binding acceptances of asset transfers.
To protect user confidentiality, the application uses filename obfuscation. When an employee signs a EULA, the resulting PDF is stored on the server using a randomized filename. This security control prevents unauthorized individuals from predicting or brute-forcing the names of stored documents. The primary attack surface resides in the application's REST API and profile management routes, which expose these file handles.
CVE-2026-55694 represents a high-severity vulnerability chain consisting of an information disclosure flaw and an insecure direct object reference (IDOR). This chain allows a low-privileged, authenticated user to completely bypass filename randomization. An attacker can resolve the randomized name of any user's EULA and download the underlying file, undermining tenant and user isolation boundaries.
The core of the vulnerability lies in the incorrect application of authorization checks inside both the API controller layer and the user profile download endpoint. The first flaw occurs in the eulas method of app/Http/Controllers/Api/UsersController.php. When checking permissions, the code invokes $this->authorize('view', User::class). In the Laravel framework, passing a class string instead of an object instance queries class-level privileges. This check determines if the requester has permission to view users in general, rather than validating if they are authorized to access the specific user record mapped to the target identifier.
The second flaw is situated within app/Http/Controllers/ProfileController.php inside the getStoredEula method. The function retrieves the associated database entry from the action_logs table using the requested filename. To verify authorization, the system compares the authenticated user's ID directly with the log entry's target_id using the expression auth()->id() != $logentry->target_id. Because the target_id column is polymorphic, it represents different entities depending on the log type, such as an asset, accessory, or consumable, rather than strictly a user ID.
This polymorphic representation creates an identifier comparison bypass. If a low-privileged user with ID 15 attempts to access a EULA associated with an action log where the target is Asset ID 15, the application evaluates the conditional check as true. Furthermore, the check permits access if the user holds generic class-level permissions to view both users and assets, bypassing organization and company-scoping boundaries.
Below is a flowchart mapping the vulnerable logical execution path:
To understand the precise vulnerability mechanics, we compare the original source code with the corrected version from the official patch repository. The vulnerability in the API layer was corrected by modifying the parameter passed to the authorization function. By changing the class name parameter to a model instance, the application correctly switches from a class-level policy check to an instance-specific validation.
// VULNERABLE - app/Http/Controllers/Api/UsersController.php
public function eulas(User $user, ActionlogsTransformer $transformer)
{
// Evaluates general class view permission only
$this->authorize('view', User::class);
$eulas = $user->eulas;
// ...
}
// PATCHED - app/Http/Controllers/Api/UsersController.php
public function eulas(User $user, ActionlogsTransformer $transformer)
{
// Correctly evaluates specific instance ownership and company scoping
$this->authorize('view', $user);
$eulas = $user->eulas;
// ...
}In the profile file download handler, the custom comparison block was completely removed. The updated logic utilizes Laravel's built-in eager loading to fetch the related user and target objects, and then delegates the authorization logic to the corresponding policy handlers. This prevents null dereferences and secures the file stream against IDOR vectors.
// VULNERABLE - app/Http/Controllers/ProfileController.php
public function getStoredEula($filename)
{
$filename = basename((string) $filename);
$logentry = Actionlog::where('filename', $filename)->first();
// Insecure polymorphic comparison and over-permissive class-level check
$allowed_to_view_users_assets = Gate::allows('view', User::class) && Gate::allows('view', Asset::class);
if (auth()->id() != $logentry->target_id && ! $allowed_to_view_users_assets) {
return redirect()->route('account')->with('error', trans('general.generic_model_not_found', ['model' => 'file']));
}
// ...
}
// PATCHED - app/Http/Controllers/ProfileController.php
public function getStoredEula($filename)
{
$filename = basename((string) $filename);
// Eagerly load relationships to resolve polymorphic target safely
$logentry = Actionlog::where('filename', $filename)->with('user', 'target')->first();
if (! $logentry) {
return redirect()->back()->with('error', trans('general.record_not_found'));
}
// Direct delegation to model instance policy checks
$this->authorize('view', $logentry->target);
$this->authorize('view', $logentry->user);
// ...
}Exploitation of this vulnerability requires network connectivity to an active Snipe-IT web deployment and standard user credentials. The attacker must first authenticate to the application as a standard user. Because the endpoint does not require administrative or asset-manager privileges, the attacker uses their own API bearer token or active session cookie to begin the attack sequence.
First, the attacker identifies a target user's database ID. The database ID is typically a sequentially assigned integer, making discovery trivial through standard enumeration techniques or general system interface inspection. Once the target ID is known, the attacker sends an authenticated GET request to the vulnerable endpoint at /api/v1/users/{target_id}/eulas. The server responds with JSON metadata representing the target's signed EULAs, which exposes the specific, randomized filename.
Second, the attacker requests the exposed filename using the vulnerable /account/stored-eula-file/{filename} route. If the attacker's own user ID matches the polymorphic target_id of the underlying action log (e.g., matching a log entry for an unrelated asset assignment), or if they possess general view permissions for users and assets, the server bypasses the access restrictions. The application retrieves the PDF file from storage and returns a 200 OK HTTP status alongside the binary payload.
The security impact of CVE-2026-55694 is highly significant for organizations that process sensitive agreements. Signed EULAs are legal instruments. They commonly contain the employee's full name, internal username, system email address, asset configurations, specific serial numbers, and physical or digital signatures. Unauthorized exposure of these elements compromises employee privacy and provides an attacker with reconnaissance data for subsequent social engineering attacks.
From an architecture perspective, this vulnerability represents a complete bypass of multi-tenant boundaries. In setups utilizing Snipe-IT's Full Multiple Companies Support (FMCS), different organizations share the same database instance but are strictly segmented. Because the vulnerable profile controller relied on class-level and polymorphic ID matching, the boundary is ignored. An attacker in Company A can read the signed agreements of users belonging to Company B, exposing proprietary enterprise data.
The CVSS v4.0 base score is rated at 7.1 (High) with the vector CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N. This calculation reflects a network-based attack vector with low complexity, requiring low privileges, with high confidentiality impact on the core system, and zero impact on integrity or availability. The vulnerability represents a severe threat to data classification controls.
The definitive solution is to upgrade the Snipe-IT installation to version 8.6.3 or later. This release updates the code logic to enforce instance-level authorization and eliminates the polymorphic target identifier mismatch. The update is applied by checking out the tag v8.6.3 from the git repository and running dependency updates.
If immediate software upgrades are not possible, administrators must implement network-level controls to block the vulnerable routes. Using a reverse proxy, such as Nginx or Apache, administrators can intercept incoming traffic and reject requests containing the specific URI paths. While this restricts normal users from viewing their own signed files via these endpoints, it prevents unauthorized exposure until a formal patch can be deployed.
An inspection of the remediated code confirms that the fix is comprehensive. By migrating the logic to Laravel's native policies, the application ensures that all company-scoping boundaries and asset verification steps are consistently applied. Security teams should audit their database logs for any anomalous requests directed towards the /api/v1/users EULA paths to identify potential exploitation attempts.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Snipe-IT Grokability | < 8.6.3 | 8.6.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-639 |
| Attack Vector | Network (AV:N) |
| CVSS v4.0 Score | 7.1 (High) |
| Exploit Status | None |
| KEV Status | Not Listed |
| Ransomware Association | No |
| Vulnerability Class | Information Disclosure & IDOR Chain |
The system fails to prevent a user from accessing resources by altering a key, such as an ID, that determines which resource is retrieved.
GeoLens before version 1.2.4 contains multiple critical-tier security vulnerabilities including improper authorization in metadata access, tile cache scope leakage, dataset title enumeration, weak default credentials, and denial of service via STAC POST search.
Snipe-IT is an IT asset/license management system. Prior to 8.6.3, any activated account can request /maintenances/{id} and read maintenance records for assets in the same company without asset or maintenance permission. app/Http/Controllers/MaintenancesController.php show() renders the record without authorize(), while company-scoped route-model binding only prevents access to other companies. Disclosed fields include asset tags, suppliers, purchase costs, notes, and dates. This issue is fixed in version 8.6.3.
A Stored DOM-based Cross-Site Scripting (DOM XSS) vulnerability exists in Snipe-IT versions prior to 8.6.2. The vulnerability occurs when a stored manufacturer or supplier name is converted to CamelCase and rendered within the 'data-selected-count-id' attribute of a table. Client-side JavaScript retrieves this decoded attribute and performs unsafe string concatenation, passing it directly into jQuery's '.after()' method, enabling authenticated attackers to execute arbitrary JavaScript in the victim's session.
CVE-2026-62673 (also known as CVE-2026-62230 and GHSA-vwg3-w8w3-pc79) is a high-severity security bypass vulnerability in the Grav CMS. It permits unauthenticated remote attackers to circumvent directory and file access policies defined in Apache .htaccess. This flaw allows direct retrieval of sensitive configuration files, system-level credentials, and database equivalents from case-insensitive host filesystems.
A credential disclosure vulnerability in the mcp-searxng NPM package prior to version 1.12.0 allows attackers to recover plain-text SearXNG Basic Authentication credentials. The application exposes these credentials via console logs (stderr), MCP logging notifications, validation error messages, and JSON-RPC error responses. This occurs because the application lacks comprehensive sanitization across diagnostic boundaries when credentials are parsed from the SEARXNG_URL environment variable.
A detailed technical analysis of CVE-2026-61711, an input validation flaw in Moby BuildKit prior to version 0.31.1. The flaw allows unauthorized or custom frontends to construct build execution environments where Seccomp and AppArmor configurations are completely disabled by supplying an invalid protobuf enum index, resulting in an elevated kernel-level attack surface inside the build sandbox.