All vulnerabilities
CVE-2026-62368GHSA-p9h3-gvpq-5539

snipe/snipe-it: Snipe-IT: Stored XSS via Custom Field name in asset-list column headers

grokability snipe/snipe-itcomposerLibraries & packages
CVSS
8.1High
ExploitationPublic exploit codeCISA's assessment says proof of concept code is public, assessed 24 Sep 2026. Not in the KEV catalogCISA via CVE List
Exploit odds (EPSS)0.35%Chance of exploitation activity in the next 30 days, higher than 27% of CVEs. Scored 23 Oct 2026FIRST EPSS
Fixed in8.7.0Fixed versionGitHub
Published24 Sep 2026Updated 24 Sep 2026CVE List

What fixes it

  • 8.7.0snipe/snipe-it, composerGitHubcomposer require "snipe/snipe-it:^8.7.0"
  • 8.7.0snipe/snipe-it, PackagistOSVcomposer require "snipe/snipe-it:^8.7.0"

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Impact

A user with the "customfields.create" permission can store HTML/JS in a Custom Field name, which is later rendered as an asset-list column title WITHOUT escaping at app/Presenters/AssetPresenter.php line 364 ('title' => $field->name) and injected into the table header by the bundled bootstrap-table plugin. It executes for anyone who opens an asset list (e.g. /hardware), including superusers, on page load with no interaction. Since "customfields.create" can be granted to non-superusers, a lower-privileged user gets script execution in a superuser's session -> privilege escalation.

STEPS TO REPRODUCE

  1. As a user with "customfields.create", create a Custom Field named: <img src=x onerror=alert(1)>
  2. Add the field to a fieldset that is associated with an asset model.
  3. Open /hardware -> the payload executes on load.

DEMONSTRATED IMPACT An account holding ONLY "customfields.create" (HTTP 403 on /users) planted a payload that, when a superuser opened /hardware, issued an authenticated request in that session and granted the attacker's own account the "superuser" permission (afterwards: GET /users = 200, isSuperUser() = true).

ROOT CAUSE

  • Blade {{ }} encodes the data-columns attribute, but the browser decodes it back before bootstrap-table reads the title; bootstrap-table then renders the header title unescaped because its table-level "escape" option defaults to false and is never enabled. (The per-column 'escape' => true covers cell values, not the header title.)

Patches

Patched in https://github.com/grokability/snipe-it/commit/58754e4e3b86b58a0c4523012ef04a2ae990d2c8

Text from GitHub Advisory Database

Affected versions 53

  • snipe/snipe-it, composer< 8.7.0GitHub
  • snipe-itaffected: < 8.7.0CVE List
  • snipe/snipe-it, Packagistfrom first release, fixed in 8.7.0OSV
  • snipe/snipe-it, Packagist3.2.0OSV
  • snipe/snipe-it, Packagistv0.1.0OSV
  • snipe/snipe-it, Packagistv0.1.1OSV
  • snipe/snipe-it, Packagistv0.1.2OSV
  • snipe/snipe-it, Packagistv0.2.0OSV
  • snipe/snipe-it, Packagistv0.3.0-alphaOSV
  • snipe/snipe-it, Packagistv0.3.10-alphaOSV
  • snipe/snipe-it, Packagistv0.3.11-alphaOSV
  • snipe/snipe-it, Packagistv0.3.7-alphaOSV
  • snipe/snipe-it, Packagistv0.3.8-alphaOSV
  • snipe/snipe-it, Packagistv0.3.9-alphaOSV
  • snipe/snipe-it, Packagistv1.0OSV
  • snipe/snipe-it, Packagistv1.1OSV
  • snipe/snipe-it, Packagistv1.2.0OSV
  • snipe/snipe-it, Packagistv1.2.1OSV
  • snipe/snipe-it, Packagistv1.2.10OSV
  • snipe/snipe-it, Packagistv1.2.11OSV
  • snipe/snipe-it, Packagistv1.2.2OSV
  • snipe/snipe-it, Packagistv1.2.3OSV
  • snipe/snipe-it, Packagistv1.2.3-betaOSV
  • snipe/snipe-it, Packagistv1.2.4OSV
  • snipe/snipe-it, Packagistv1.2.4-betaOSV
  • snipe/snipe-it, Packagistv1.2.5OSV
  • snipe/snipe-it, Packagistv1.2.6OSV
  • snipe/snipe-it, Packagistv1.2.6-betaOSV
  • snipe/snipe-it, Packagistv1.2.6.1OSV
  • snipe/snipe-it, Packagistv1.2.7OSV
  • snipe/snipe-it, Packagistv1.2.7-betaOSV
  • snipe/snipe-it, Packagistv1.2.8OSV
  • snipe/snipe-it, Packagistv1.2.9OSV
  • snipe/snipe-it, Packagistv2.0OSV
  • snipe/snipe-it, Packagistv2.0-RC-1OSV
  • snipe/snipe-it, Packagistv2.0-betaOSV
  • snipe/snipe-it, Packagistv2.0.1OSV
  • snipe/snipe-it, Packagistv2.0.2OSV
  • snipe/snipe-it, Packagistv2.0.3OSV
  • snipe/snipe-it, Packagistv2.0.4OSV
  • snipe/snipe-it, Packagistv2.0.5OSV
  • snipe/snipe-it, Packagistv2.0.6OSV
  • snipe/snipe-it, Packagistv2.1.0OSV
  • snipe/snipe-it, Packagistv2.1.1OSV
  • snipe/snipe-it, Packagistv2.1.2OSV
  • snipe/snipe-it, Packagistv3.0OSV
  • snipe/snipe-it, Packagistv3.0-alphaOSV
  • snipe/snipe-it, Packagistv3.0-alpha2OSV
  • snipe/snipe-it, Packagistv3.0-beta.1OSV
  • snipe/snipe-it, Packagistv3.0-beta.2OSV
  • snipe/snipe-it, Packagistv3.0-beta.3OSV
  • snipe/snipe-it, Packagistv3.0.0-betaOSV
  • snipe/snipe-it, Packagistv3.1.0OSV

References 4