CVE-2026-62368 Overview
Snipe-IT, an open-source IT asset and license management system, contains a stored Cross-Site Scripting (XSS) vulnerability in versions prior to 8.7.0. A user holding the customfields.create permission can inject HTML or JavaScript markup into the CustomField.name field. The app/Presenters/AssetPresenter.php component then renders that value as an unescaped bootstrap-table header title. When another authenticated user loads an asset-list page tied to the affected fieldset, the attacker's payload executes in the victim's browser session. The flaw is tracked as [CWE-79] and is fixed in Snipe-IT version 8.7.0.
Critical Impact
Stored XSS enables same-origin data theft and authenticated actions on behalf of the victim, including full privilege escalation when a superuser renders the compromised asset list.
Affected Products
- Snipe-IT (snipeitapp/snipe-it) versions prior to 8.7.0
- Deployments exposing the custom fields management workflow to non-superuser accounts
- Instances where privileged users browse asset lists built from untrusted fieldsets
Discovery Timeline
- 2026-09-24 - CVE-2026-62368 published to the National Vulnerability Database (NVD)
- 2026-09-29 - Last updated in NVD database
Technical Details for CVE-2026-62368
Vulnerability Analysis
The vulnerability resides in how Snipe-IT constructs the column metadata for the bootstrap-table component used to render asset lists. The AssetPresenter::dataTableLayout() method iterates over CustomField records and assigns $field->name directly to the title property of each column definition. That value is serialized into JSON and emitted into the page, where bootstrap-table renders the title as HTML in the table header.
A developer comment in the pre-patch code assumed that Blade view escaping downstream was sufficient, but the column title is consumed by client-side JavaScript rather than a Blade template. Any markup stored in CustomField.name therefore executes on page load. Because the payload runs inside an authenticated Snipe-IT session, it inherits the victim's privileges and can issue API calls, read same-origin data, or escalate privileges when a superuser is targeted.
Root Cause
The root cause is missing output encoding on attacker-controlled data flowing from the database into a client-side rendering context. The patch replaces 'title' => $field->name with 'title' => e($field->name), applying Laravel's HTML entity escaping before the string reaches the browser.
Attack Vector
Exploitation requires an account with the customfields.create permission. The attacker creates or updates a custom field whose name contains HTML or JavaScript markup, then waits for another user, ideally a superuser, to view an asset list that includes the compromised fieldset. The payload executes in the victim's browser under the Snipe-IT origin, enabling session abuse and privileged actions.
$fields = CustomField::whereHas('fieldset', function ($query) {
$query->whereHas('models');
})->get();
-
- // Note: We do not need to e() escape the field names here, as they are already escaped when
- // they are presented in the blade view. If we escape them here, custom fields with quotes in their
- // name can break the listings page. - snipe
+
foreach ($fields as $field) {
$layout[] = [
'field' => $field->db_column,
'searchable' => true,
'sortable' => true,
'switchable' => true,
- 'title' => $field->name,
+ 'title' => e($field->name),
'formatter' => 'customFieldsFormatter',
'escape' => true,
'class' => ($field->field_encrypted == '1') ? 'css-padlock' : '',
Source: GitHub commit 58754e4 — patch applies e() escaping to the custom field name before it reaches the bootstrap-table header.
Detection Methods for CVE-2026-62368
Indicators of Compromise
- Rows in the custom_fields table where the name column contains HTML tags, <script>, on*= attributes, or JavaScript URI schemes.
- Audit log entries showing customfields.create or customfields.update activity from non-administrative accounts shortly before anomalous session behavior.
- Unexpected outbound requests from authenticated administrative browsers to attacker-controlled hosts after loading an asset list.
Detection Strategies
- Query the Snipe-IT database for custom field names matching regular expressions such as <[^>]+> or javascript: to surface injected markup.
- Review web server access logs for POSTs to /custom_fields and /custom_fields/* originating from accounts that should not hold the customfields.create permission.
- Deploy a Content Security Policy (CSP) in report-only mode to capture inline script violations originating from /hardware and other asset-list routes.
Monitoring Recommendations
- Alert on administrator or superuser sessions that generate unusual API calls immediately after viewing an asset-list page.
- Monitor Snipe-IT application logs for permission changes and new privileged account creation that follow custom field modifications.
- Enable browser-side CSP violation reporting and forward events to the SIEM for correlation with Snipe-IT audit events.
How to Mitigate CVE-2026-62368
Immediate Actions Required
- Upgrade all Snipe-IT instances to version 8.7.0 or later without delay.
- Audit assignments of the customfields.create permission and remove it from accounts that do not require custom field authoring.
- Inspect existing CustomField records for HTML or script content and sanitize or delete affected entries before upgrading.
Patch Information
The fix is included in Snipe-IT v8.7.0. Technical details are published in GHSA-p9h3-gvpq-5539 and the corresponding upstream commit, which applies Laravel's e() helper to the custom field name before it is emitted into the bootstrap-table layout.
Workarounds
- Restrict the customfields.create and customfields.update permissions to trusted administrators until the patch is applied.
- Enforce a strict Content Security Policy that disallows inline scripts on asset-list routes to limit payload execution.
- Place Snipe-IT behind a web application firewall (WAF) rule that blocks requests containing HTML tags in the name parameter of custom field endpoints.
# Upgrade Snipe-IT to the patched release
cd /var/www/snipe-it
php artisan down
git fetch --tags
git checkout v8.7.0
composer install --no-dev --prefer-source
php artisan migrate --force
php artisan config:clear && php artisan cache:clear
php artisan up
# Identify custom fields containing suspicious markup
mysql -e "SELECT id, name FROM snipeit.custom_fields \
WHERE name REGEXP '<[^>]+>|javascript:|on[a-z]+=';"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

