Canva MCP — cross-origin OAuth account takeover

Page origin:  |  Target: https://mcp.canva.com  |  Header: X-Bug-Bounty: bugcrowdninja
Authorized testing under Canva's Bugcrowd program. Test account afrozenkiwi@gmail.com consents to itself.

1 · Register a public OAuth client cross-origin

redirect_uri:
no auth required, ACAO reflects this page's origin
(idle)

2 · Open Canva consent screen

→ 302 to www.canva.com — URL bar must show real canva.com
(idle)

3 · Paste the URL the browser landed on after Allow

(idle)

4 · Exchange code for bearer (cross-origin, no client_secret, no code_verifier)

response body must be JS-readable (ACAO reflected)
(idle)

5 · List MCP tools (cross-origin Bearer)

expect 22 tools, ~46 KB body
(idle)

6 · Read real victim data (search-designs, read-only)

renders the victim's design list as a clean table
Raw JSON
(idle)

6b · Export one design (read primitive — presigned S3 URL)

extracts the design as PNG via a presigned S3 URL
(idle)

7 · Persistence — refresh-token grant cross-origin

(idle)
Show variables
{}
Notes on redirect_uri values that work
The Canva /authorize allowlist accepts these hosts (for any registered client):
  https://127.0.0.1:<port>/<path>       — needs a localhost listener
  https://localhost/<path>
  https://www.cursor.com/<path>          — code lands on a public domain (browser, history, extensions)
  https://chatgpt.com/<path>
  https://platform.openai.com/<path>
  https://claude.ai/<path>
  https://claude.com/<path>              — and this includes:
  https://claude.com/redirect/<FULL URL> — open redirect to ANY host. Use this to deliver
                                          the code to an attacker-controlled server with no
                                          victim cooperation.

Replace 127.0.0.1:1337 with your own server URL to test the full pure-web chain.