# Arbitrary read on s3://shopify-delivery-app-storage/files

Attacker-controlled attachment filename with ../ traversal let any Shopify merchant read other shops' uploaded files from the shared S3 bucket via a signed download link.

- Payout: $1,500
- Severity: high
- Program: Shopify
- Credited: brakhane
- Disclosed: 2015-10-20
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/94087
- Library page: https://bugbountylibrary.com/r/h1%3A94087
- Tags: domain:web3 impact:data-leak kind:bounty platform:hackerone sev:high tech:s3 technique:source-review vuln:access-control vuln:idor vuln:path-traversal

**Target:** Product attachment upload/download (S3-backed delivery app)
**Root cause:** The fog-aws gem path-normalizes the user-controlled filename, so '../' sequences in attachment[filepath] escape the attacker's own S3 prefix and resolve to another shop's object key; the app then signs a download link for that key.
**Steps:**
1. Victim uploads `a.png` to a product; stored at `s3://shopify-delivery-app-storage/files/myhackeronestore.myshopify.com/5682196162/a.png`.
2. Attacker uploads `b.png` to their own shop but sets `attachment[filepath]` to `b.png/../../../../files/myhackeronestore.myshopify.com/5682196162/a.png` in the `/attachments` call.
3. Generate a manual download link for the new attachment; page shows the traversal string as filename.
4. Click download to receive a valid signed URL fetching the victim's `a.png`.
**How found:** Researcher reasoned that the app lets the user influence the S3 bucket key via attachment[filepath], then tested whether path traversal in that parameter would resolve to another shop's prefix and whether the download-link generator would sign it.
**Exploitation:** Attacker needs only a merchant account and knowledge of the target's bucket key (shop domain + product/attachment ID). Uploading with a traversal filename causes the backend to sign a download URL for the victim's object, which the attacker then fetches directly from S3.
**Insight:** When an app stores user uploads in a shared bucket keyed by tenant prefix, try traversal sequences in any user-controlled filename/path parameter and check whether the download/signing step normalizes it into another tenant's key.
