# Get analytics token using only apps permission

Staff with only apps permission queried GraphQL for embedded analytics tokens of report-reading apps, then used them to read store sales reports.

- Payout: hidden
- Severity: medium
- Program: Shopify
- Found by: jmp_35p
- Disclosed: 2020-08-18
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/901775
- Library page: https://bugbountylibrary.com/r/h1%3A901775
- Tags: area:web domain:web impact:data-leak kind:bounty platform:hackerone sev:medium tech:graphql technique:source-review vuln:access-control vuln:idor

**Target:** Shopify admin GraphQL appByKey and analytics.shopify.com /validate endpoint
**Root cause:** The appByKey GraphQL query returns legacyEasdkAnalyticsToken for any app without enforcing that the caller has dashboard/reports permission, only apps permission.
**Steps:**
1. As staff with only apps permission, send GraphQL `query EmbeddedAppAnalyticsToken($apiKey:String!){appByKey:appByKey(apiKey:$apiKey){id installation{id legacyEasdkAnalyticsToken __typename}__typename}}` with `apiKey` of a report-reading app (e.g. POS app).
2. Extract `legacyEasdkAnalyticsToken` from response.
3. POST to `https://analytics.shopify.com/validate?beta=true&dataOnly=false` with `Content-Type: application/x-www-form-urlencoded`, `Origin: https://foobar.myshopify.com`, body `q[]=SHOW orders, gross_sales, ... FROM sales SINCE -30d UNTIL today ORDER BY day&source=new-admin&token={token}`.
4. Read store sales report data returned.
**How found:** Noticed apps with analytics read scope embed an analyticsToken, and that the token endpoint requires dashboard/reports permission while the GraphQL appByKey path did not enforce it.
**Exploitation:** Attacker with limited apps permission enumerates app apiKeys, pulls embedded analytics tokens via GraphQL, and replays them against analytics.shopify.com to query sales reports they lack permission to view.
**Insight:** When a permission gate exists on one endpoint (reportify/token.json), check alternate GraphQL fields like appByKey.installation.legacyEasdkAnalyticsToken that expose the same secret without the gate.

