# SSRF vulnerability in AppSheet - Google VRP

AppSheet webhook feature allowed SSRF to GCP metadata server, leaking the app's service account access token; fix bypassed via alternate metadata header.

- Payout: $6,267
- Severity: high
- Program: Google
- Credited: David Nechuta
- Disclosed: 2021-12-05
- Write-up quality: 7/10
- Original: https://nechudav.blogspot.com/2021/12/ssrf-vulnerability-in-appsheet-google.html
- Library page: https://bugbountylibrary.com/r/blog%3Anechudav-blogspot-com-2021-12-ssrf-vulnerability-in-appsheet-google-html
- Tags: domain:cloud impact:data-leak impact:internal-access kind:bounty platform:blog sev:high tech:gcp technique:chained technique:incomplete-fix vuln:ssrf

**Target:** AppSheet Workflow webhook HTTP client / GCP metadata server
**Root cause:** Webhook URL was fetched server-side without restricting internal/metadata addresses; the fix filtered only the Metadata-Flavor header, leaving X-Google-Metadata-Request accepted by the metadata server.
**Steps:**
1. Create AppSheet workflow rule triggering a webhook on table row change
2. Set webhook URL to `http://<attacker>/computeMetadata/v1beta1/instance/service-accounts/default/token` with 301 redirect to `http://169.254.169.254/...` (POST→GET via redirect)
3. Trigger rule by adding a row; read response body from app logs containing access token
4. After fix: point webhook directly to `http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token` with header `X-Google-Metadata-Request: True`
5. Trigger and read token from logs
**How found:** Explored the Workflows webhook feature as a server-side request primitive; noticed only POST/DELETE/PATCH allowed, so used 301 redirect to convert POST to GET for metadata API; after fix, probed which metadata security headers were filtered by testing both header variants.
**Exploitation:** Attacker controls a webhook URL fetched by AppSheet's backend; redirect or direct request reaches GCP metadata endpoint, and the response body (containing the service account OAuth token) is written to application logs readable by the attacker.
**Escalation:** Bypassed the initial fix by switching to the undocumented X-Google-Metadata-Request header after Metadata-Flavor was filtered.
**Insight:** When a fix filters one known auth/security header, enumerate alternate equivalent headers (e.g. X-Google-Metadata-Request vs Metadata-Flavor) and undocumented method support on the target endpoint; also use 301 redirects to convert disallowed methods into allowed ones.
