VYPR
Moderate severityNVD Advisory· Published Oct 6, 2023· Updated Sep 19, 2024

Cross-site Scripting (XSS) - Stored in snipe/snipe-it

CVE-2023-5452

Description

Cross-site Scripting (XSS) - Stored in GitHub repository snipe/snipe-it prior to v6.2.2.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Stored XSS in Snipe-IT asset history allows authenticated attackers to inject arbitrary JavaScript via location name fields.

Vulnerability

Overview

CVE-2023-5452 is a stored cross-site scripting (XSS) vulnerability in Snipe-IT, an open-source IT asset management system. The root cause lies in the asset history component, where location names (old and new values) were rendered without proper escaping. The commit that fixes the issue [2] shows the addition of the e() helper function to escape output, confirming that unsanitized user-controlled data was being stored and later displayed in the web interface.

Exploitation

An authenticated user with permission to edit asset details—specifically the location fields—can inject malicious JavaScript into the location name. When other users (including administrators) view the asset history, the injected script executes in their browser. No special network access is required beyond normal web application usage; the attacker simply needs to be able to modify asset metadata [1][3].

Impact

Successful exploitation allows the attacker to execute arbitrary JavaScript in the context of the victim's session. This can lead to session hijacking, credential theft, unauthorized actions performed on behalf of the victim, or defacement of the application interface. The stored nature of the XSS means the payload persists and affects all subsequent viewers of the affected asset history.

Mitigation

The vulnerability is fixed in Snipe-IT version 6.2.2. Users are strongly advised to upgrade immediately. The fix is visible in the referenced commit [2], which escapes location name values before rendering. No workarounds have been publicly documented; upgrading is the recommended course of action. The issue was reported via the huntr.dev bug bounty platform [4].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
snipe/snipe-itPackagist
< 6.2.26.2.2

Affected products

2

Patches

1
eea2eabaeef1

Escaping asset history old/new values

https://github.com/snipe/snipe-itsnipeOct 6, 2023via ghsa
1 file changed · +13 11
  • app/Http/Transformers/ActionlogsTransformer.php+13 11 modified
    @@ -178,24 +178,26 @@ public function changedInfo(array $clean_meta)
     
     
             if(array_key_exists('rtd_location_id',$clean_meta)) {
    -            $clean_meta['rtd_location_id']['old'] = $clean_meta['rtd_location_id']['old'] ? "[id: ".$clean_meta['rtd_location_id']['old']."] ". $location->find($clean_meta['rtd_location_id']['old'])->name : trans('general.unassigned');
    -            $clean_meta['rtd_location_id']['new'] = $clean_meta['rtd_location_id']['new'] ? "[id: ".$clean_meta['rtd_location_id']['new']."] ". $location->find($clean_meta['rtd_location_id']['new'])->name : trans('general.unassigned');
    +            $clean_meta['rtd_location_id']['old'] = $clean_meta['rtd_location_id']['old'] ? "[id: ".$clean_meta['rtd_location_id']['old']."] ". e($location->find($clean_meta['rtd_location_id']['old'])->name) : trans('general.unassigned');
    +            $clean_meta['rtd_location_id']['new'] = $clean_meta['rtd_location_id']['new'] ? "[id: ".$clean_meta['rtd_location_id']['new']."] ". e($location->find($clean_meta['rtd_location_id']['new'])->name) : trans('general.unassigned');
                 $clean_meta['Default Location'] = $clean_meta['rtd_location_id'];
                 unset($clean_meta['rtd_location_id']);
             }
    -        if(array_key_exists('location_id', $clean_meta)) {
    -            $clean_meta['location_id']['old'] = $clean_meta['location_id']['old'] ? "[id: ".$clean_meta['location_id']['old']."] ".$location->find($clean_meta['location_id']['old'])->name : trans('general.unassigned');
    -            $clean_meta['location_id']['new'] = $clean_meta['location_id']['new'] ? "[id: ".$clean_meta['location_id']['new']."] ".$location->find($clean_meta['location_id']['new'])->name : trans('general.unassigned');
    +
    +        if (array_key_exists('location_id', $clean_meta)) {
    +            $clean_meta['location_id']['old'] = $clean_meta['location_id']['old'] ? "[id: ".$clean_meta['location_id']['old']."] ".e($location->find($clean_meta['location_id']['old'])->name): trans('general.unassigned');
    +            $clean_meta['location_id']['new'] = $clean_meta['location_id']['new'] ? "[id: ".$clean_meta['location_id']['new']."] ".e($location->find($clean_meta['location_id']['new'])->name) : trans('general.unassigned');
                 $clean_meta['Current Location'] = $clean_meta['location_id'];
                 unset($clean_meta['location_id']);
             }
    +
             if(array_key_exists('model_id', $clean_meta)) {
     
                 $oldModel = $model->find($clean_meta['model_id']['old']);
    -            $oldModelName = $oldModel->name ?? trans('admin/models/message.deleted');
    +            $oldModelName = $oldModel ? e($oldModel->name) : trans('admin/models/message.deleted');
     
                 $newModel = $model->find($clean_meta['model_id']['new']);
    -            $newModelName = $newModel->name ?? trans('admin/models/message.deleted');
    +            $newModelName = $newModel ? e($newModel->name) : trans('admin/models/message.deleted');
     
                 $clean_meta['model_id']['old'] = "[id: ".$clean_meta['model_id']['old']."] ".$oldModelName;
                 $clean_meta['model_id']['new'] = "[id: ".$clean_meta['model_id']['new']."] ".$newModelName; /** model is required at asset creation */
    @@ -206,10 +208,10 @@ public function changedInfo(array $clean_meta)
             if(array_key_exists('company_id', $clean_meta)) {
     
                 $oldCompany = $company->find($clean_meta['company_id']['old']);
    -            $oldCompanyName = $oldCompany->name ?? trans('admin/companies/message.deleted');
    +            $oldCompanyName = $oldCompany ? e($oldCompany->name) : trans('admin/company/message.deleted');
     
                 $newCompany = $company->find($clean_meta['company_id']['new']);
    -            $newCompanyName = $newCompany->name ?? trans('admin/companies/message.deleted');
    +            $newCompanyName = $newCompany ? e($newCompany->name) : trans('admin/company/message.deleted');
     
                 $clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."] ". $oldCompanyName : trans('general.unassigned');
                 $clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ". $newCompanyName : trans('general.unassigned');
    @@ -219,10 +221,10 @@ public function changedInfo(array $clean_meta)
             if(array_key_exists('supplier_id', $clean_meta)) {
     
                 $oldSupplier = $supplier->find($clean_meta['supplier_id']['old']);
    -            $oldSupplierName = $oldSupplier->name ?? trans('admin/suppliers/message.deleted');
    +            $oldSupplierName = $oldSupplier ? e($oldSupplier->name) : trans('admin/suppliers/message.deleted');
     
                 $newSupplier = $supplier->find($clean_meta['supplier_id']['new']);
    -            $newSupplierName = $newSupplier->name ?? trans('admin/suppliers/message.deleted');
    +            $newSupplierName = $newSupplier ? e($newSupplier->name) : trans('admin/suppliers/message.deleted');
     
                 $clean_meta['supplier_id']['old'] = $clean_meta['supplier_id']['old'] ? "[id: ".$clean_meta['supplier_id']['old']."] ". $oldSupplierName : trans('general.unassigned');
                 $clean_meta['supplier_id']['new'] = $clean_meta['supplier_id']['new'] ? "[id: ".$clean_meta['supplier_id']['new']."] ". $newSupplierName : trans('general.unassigned');
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.