# H1514 Stored XSS on Wholesale sales channel allows cross-organization data leakage

Stored XSS in Wholesale sales channel's price_list[csv_file_name] parameter lets an attacker with Apps permission pivot into other shops' wholesale data.

- Payout: hidden
- Severity: medium
- Program: Shopify
- Found by: cablej
- Disclosed: 2019-11-01
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/423454
- Library page: https://bugbountylibrary.com/r/h1%3A423454
- Tags: area:web domain:web impact:integrity impact:internal-access impact:pii-leak kind:bounty platform:hackerone sev:medium technique:source-review vuln:xss

**Target:** Wholesale sales channel price list import (POST /admin/shops/x/price_lists/x)
**Root cause:** The price_list[csv_file_name] value is stored and rendered into a JavaScript context without proper escaping, allowing script injection.
**Steps:**
1. Add Wholesale integration at https://wholesale.shopifyapps.com.
2. Create a new price list import with a CSV containing a product SKU.
3. After creating the price list, intercept `POST /admin/shops/x/price_lists/x`.
4. Set `price_list[csv_file_name]` to `sample-csv-sku.csv"-alert(document.domain)-"`.
5. Revisit the price list page; payload fires on https://wholesale.shopifyapps.com.
**How found:** Researcher noticed the CSV filename was reflected into the price list page and tested injecting a quote-break payload into the stored filename parameter.
**Exploitation:** Attacker with Apps permission on a shared shop injects script into a price list name; since wholesale.shopifyapps.com is shared across shops, the script executes in the context of any owner's other stores, exposing customer PII and allowing modification of Wholesale data.
**Escalation:** Cross-organization pivot: shared origin across shops turns a single-shop injection into access to every shop the victim owner controls.
**Insight:** On multi-tenant SaaS where a single app origin serves many tenants, any stored XSS in tenant-controlled fields becomes cross-tenant; look at filename/name fields echoed into JS contexts.

