Skip to content

The Shopify Bug Bounty Program

This page ties the previous chapters to a real, well-run target: Shopify’s public bug bounty program on HackerOne. Shopify has invited security research for years, pays for valid findings, and publishes a clear policy — which makes it an excellent place to practice authorized testing. The essential discipline: read their current policy, practice on your own development store and test app, and keep every action non-destructive and in scope.

Shopify is not a soft target — it has a large security team, mature defenses, and thousands of researchers have already looked. That shapes strategy:

  • Depth over breadth. The easy reflected-XSS-on-the-homepage bugs are gone. Value is in understanding the platform deeply — its multi-tenant model, the app/OAuth system, GraphQL authorization — and finding the logic gap others missed.
  • Your own environment first. Never learn on production. Shopify lets developers spin up free development stores and test apps; that’s your lab.
  • Read hacktivity. HackerOne publishes disclosed reports (“hacktivity”). Reading past Shopify reports teaches you which bug classes land and how good reports are written.

Shopify’s architecture from a tester’s view

Section titled “Shopify’s architecture from a tester’s view”

You test what you understand. Here’s the platform’s shape and where the interesting boundaries are:

Component What it is Why a tester cares
Storefront The public shop (themes, Liquid templates, checkout entry) Classic web bugs; theme/Liquid handling; input reflection
Admin GraphQL API The merchant’s back-office API (/admin/api/.../graphql.json) The richest surface: object/field authorization, per-shop scoping
Storefront API Public/customer-facing GraphQL for building storefronts Token scoping, what an unauthenticated token may read
App OAuth & access scopes Third-party apps authorize via OAuth and request scopes redirect_uri, state, scope escalation, token handling
Webhooks / HMAC Shopify calls app endpoints on events, signed with HMAC Signature verification correctness, replay
Checkout The purchase flow, discounts, Shopify Functions Business logic: price, discount, quantity, workflow
Shopify Functions Merchant-supplied logic (discounts, validation) at checkout Logic boundaries, input handling
Multipass / SSO Enables login federation for Plus merchants Token/signature handling, account linking

The unifying theme is multi-tenancy: one platform hosts millions of independent shops. The most valuable question you can ask is “can shop A ever reach shop B’s data or actions?” — a cross-shop / cross-tenant boundary break.

Do all your learning against resources you own. Two building blocks:

A development store. Shopify’s Partner program lets you create free development stores — full Shopify shops that don’t process real orders. This is where you safely try IDOR, GraphQL authorization, and checkout-logic tests without affecting anyone.

A custom/test app with your own credentials. Create an app in your Partner dashboard to get a client ID/secret and walk the real OAuth flow. Then you can exercise the Admin GraphQL API with an access token you legitimately own:

Terminal window
# Against YOUR OWN dev store, using a token YOU generated:
curl -s "https://your-dev-store.myshopify.com/admin/api/2024-10/graphql.json" \
-H "X-Shopify-Access-Token: $YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"query":"{ shop { name myshopifyDomain } }"}' | jq .

With your own store, token, and app, you can run the full terminal workflow — mitmproxy in front of the requests, curl/jq to iterate — against infrastructure you’re allowed to hammer, learning the platform before you ever look at anything in scope on the live program.

Bug classes that have historically been valuable

Section titled “Bug classes that have historically been valuable”

For authorized testing, these are the areas where Shopify bugs have repeatedly had real impact. Study them, practice them on your dev store, and pursue them only against in-scope assets:

  • Cross-shop / cross-tenant access control. The crown jewel. Any path where one shop’s credentials reach another shop’s data or admin actions. Test with two dev stores you own and try to reach store A’s objects with store B’s token — the IDOR/BOLA method, applied to Shopify’s global IDs.

  • OAuth / app authorization. Flaws in how apps are authorized and scoped: loose redirect_uri validation, missing state, scope escalation, tokens leaking to the wrong party. See auth attacks.

  • GraphQL authorization. Object- and field-level gaps in the Admin/Storefront GraphQL APIs — reading a field or node you shouldn’t. See GraphQL attacks. Watch the query-cost model rather than trying to brute-force via aliasing.

  • Webhook / HMAC verification. Shopify signs webhooks with an HMAC over the payload using the app’s secret; an app that doesn’t verify it (or verifies it wrongly, e.g. non-constant-time comparison, or accepting an empty signature) can be fed forged events. The concept:

    verify_webhook.py
    import hmac, hashlib, base64
    # Compute the expected HMAC and compare in constant time.
    digest = hmac.new(APP_SECRET.encode(), raw_body, hashlib.sha256).digest()
    expected = base64.b64encode(digest).decode()
    ok = hmac.compare_digest(expected, received_hmac_header) # constant-time compare

    A bug is when an app skips this, uses == instead of compare_digest, or trusts an unsigned request. Test against your own app’s endpoint.

  • Business logic in checkout / discounts. Price, quantity, discount stacking, and workflow flaws in the purchase path and in Shopify Functions. The value-tampering and race-condition ideas from core web vulnerabilities apply directly — on your dev store’s checkout.

On a mature program, report quality is often what separates a paid bug from a closed one. A strong report has:

  • A clear, specific title. “Cross-shop order read via node(id:) in Admin GraphQL API,” not “IDOR found.”
  • Impact stated plainly. What can an attacker actually do, and to whom? Tie it to Shopify’s model (“a merchant on shop A can read shop B’s customer PII”). Severity follows impact.
  • Reproducible steps. Numbered, exact, copy-pasteable. Include the requests (redact your own tokens) so a triager reproduces it in minutes.
  • A minimal PoC. The smallest demonstration: two accounts and one cross-account request; one alert(document.domain) screenshot; one boolean SQLi difference. Never a data dump.
  • Remediation. Say how to fix it — “enforce object-level authorization in the node resolver,” “use constant-time HMAC comparison,” “reject unregistered redirect_uri values.”
report-skeleton.md
Title: <specific, one line — vuln + location + impact>
Assets: <exact in-scope asset from the program page>
Summary: <2-3 sentences: what, where, why it matters>
Steps to reproduce:
1. As user/store A (my dev store), do X. Request: <curl, tokens redacted>
2. As user/store B (my dev store), do Y with A's object id.
3. Observe B receives A's data. Response: <minimal excerpt>
Impact: <who is affected and how badly>
PoC: <one minimal request/screenshot — no bulk data>
Remediation: <the specific fix>

Avoiding duplicates and out-of-scope actions

Section titled “Avoiding duplicates and out-of-scope actions”
  • Check scope every time. Assets move in and out of scope; re-read the program page before testing an asset, and never touch anything marked out of scope.
  • Search hacktivity first to reduce (not eliminate) duplicates — but report anyway if you have a genuine finding; triage decides duplicates.
  • Respect the account rules. Use test/dev accounts as the policy requires; don’t test against real merchants or real customer data.
  • Stay non-destructive. No DoS, no bulk data exfiltration, no persistent defacement, no automated mass-scanning that degrades service.
  • The Shopify HackerOne program page — policy, scope, rewards, and rules. The source of truth; read it before and during testing.
  • Shopify developer docs — the Admin GraphQL API, Storefront API, OAuth, webhooks/HMAC, Functions, and Multipass references. Use them for exact endpoints, API versions, headers, and scopes rather than trusting any tutorial.
  • HackerOne hacktivity — disclosed Shopify reports; study bug classes and report quality.
  • The Shopify changelog / developer changelog — API and platform changes that open (or close) attack surface over time.
  • Shopify’s HackerOne policy and scope are authoritative and change — read them every time; this page never overrides them.
  • Learn on your own development store and test app with credentials you generated; run the full curl/jq/mitmproxy workflow there before touching in-scope live assets.
  • The platform’s defining property is multi-tenancy — the highest-value question is whether one shop can reach another’s data or actions.
  • Historically valuable classes: cross-shop access control, OAuth/app authorization, GraphQL authorization, webhook/HMAC verification, and checkout/discount business logic.
  • Great reports are specific, reproducible, minimal-PoC, and remediation-focused — and never include bulk or third-party data.
  • No DoS, no social engineering, no touching real user data. Detect, prove minimally, disclose responsibly.