GHSA-jhph-5q74-pmfx: XSS

Published Aug 28, 2026
·
Updated

Impact A low-privilege user can store an active-content payload as an asset attachment and have it served inline, same-origin, with an active Content-Type, achieving stored XSS. The application sanitizes uploads only when PHP finfo detects image/svg+xml. By submitting an XHTML document whose finfo MIME is text/xml (an allowed extension), the svg-sanitize branch is skipped, the <script> is stored raw, and the inline-serve path returns it as text/xml; charset=utf-8 with Content-Disposition: inline — which the browser renders as a live XHTML document and executes. The dedicated StorageHelper::allowSafeInline() whitelist that should have constrained inline-renderable types is never wired into the serve path.

Details Vulnerable code — sanitizer keyed on finfo MIME app/Http/Requests/UploadFileRequest.php:46-53

php $extension = $file->getClientOriginalExtension(); $filename = $nameprefix.'-'.strrandom(8).'-'.strslug(...).'.'.$file->guessExtension(); ... if ($file->getMimeType() === 'image/svg+xml') { $uploadedfile = $this->handleSVG($file); // svg-sanitize fires } else { $uploadedfile = filegetcontents($file); // stored RAW — no sanitization }

Vulnerable code — inline serve, no allowSafeInline() app/Http/Controllers/UploadedFilesController.php:103

php if (request('inline') == 'true') { $headers = ['Content-Disposition' => 'inline']; return Storage::download($path.$log->filename, $log->filename, $headers); }

StorageHelper::allowSafeInline() (app/Helpers/StorageHelper.php:88) exists to whitelist inline-renderable types but is not called here. The validation rule (UploadFileRequest::rules()) is mimes: over config('filesystems.alloweduploadextensionsforvalidator'), which includes svg, xml, and txt — so a text/xml file passes validation and bypasses the SVG sanitizer simultaneously.

POC 1. From a fresh install, as a user with only assets.view + assets.files targeting any existing asset created by admin 2. click on the asset created by admin and upload files. 3. create a XML file with the following payload and upload it.

xml <?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml"> <head><script>alert(document.cookie)</script></head> <body>hi</body> </html>

4. Noticed that it did not receive any error and the file was uploaded. 5. Now, can just get the URL and view it. (need to add the inline=true). image.png

Notice that the XSS was able to request document.cookie. This means that it is possible for low privilege user to perform XSS and perform privilege escalation to admin.

Affected Software

1 affected componentFixes available
composer/snipe/snipe-it<=8.6.1
8.6.2

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade composer/snipe/snipe-it to a version that resolves this vulnerability.

    Fixed in 8.6.2
  2. Configuration

    In app/Http/Controllers/UploadedFilesController.php (inline serve path), ensure StorageHelper::allowSafeInline() is enforced before returning inline-renderable content (the material states the whitelist exists in app/Helpers/StorageHelper.php:88 but is never wired into the serve path).

    UploadedFilesController (inline serve) allowSafeInline() = called
  3. Configuration

    In app/Http/Requests/UploadFileRequest.php: rules(), adjust the `mimes` validation (based on config('filesystems.allowed_upload_extensions_for_validator'), which includes svg, xml, and txt) to exclude XML types such as text/xml so they do not bypass the SVG sanitizer branch.

    UploadFileRequest (upload validation) rules() mimes over allowed extensions list = narrow to disallow text/xml and xml
  4. Configuration

    In app/Http/Requests/UploadFileRequest.php:46-53, do not key sanitization only on finfo detecting image/svg+xml. Ensure content that can be served inline (e.g., XML/XHTML with active content) is sanitized/blocked appropriately so an XHTML/XML payload cannot be stored raw and served inline as text/xml.

    Upload handling/sanitization SVG sanitizer trigger condition = do not rely solely on finfo MIME image/svg+xml
  5. Configuration

    In the inline serve path (where request('inline') == 'true' enables inline Content-Disposition), restrict inline serving to the dedicated StorageHelper::allowSafeInline() whitelist so low-privilege users cannot make stored active-content payloads render as live documents.

    Uploaded files inline behavior inline query/parameter = require inline=false by default or restrict inline to whitelisted types

Event History

Aug 28, 2026
Advisory Published
via GitHub·05:59 PM
Data Sourced
via GitHub·05:59 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which users can exploit this issue?

A low-privilege user who can upload an asset attachment can store the payload. Exploitation requires an XHTML document that is detected as text/xml and uses an allowed extension.

2

Who is at risk from a malicious attachment?

Users who open the uploaded attachment inline are exposed because it is served same-origin as text/xml with an inline Content-Disposition. A browser can render the document as active XHTML and execute its embedded script.

3

Does SVG upload sanitization prevent this attack?

No. Sanitization runs only when PHP finfo identifies the upload as image/svg+xml; an XHTML payload identified as text/xml bypasses that branch and is stored without sanitization.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203