# Full Read SSRF on Gitlab's Internal Grafana

Grafana's /avatar/:hash URL-decodes the hash, letting an attacker smuggle a `d` param into the gravatar fetch and chain open redirects to reach arbitrary internal hosts.

- Payout: hidden
- Severity: critical
- Program: GitLab
- Found by: rhynorater
- Disclosed: 2020-08-07
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/878779
- Library page: https://bugbountylibrary.com/r/h1%3A878779
- Tags: area:web domain:web impact:internal-access kind:bounty platform:hackerone sev:critical tech:go technique:chained technique:source-review vuln:ssrf

**Target:** Grafana /avatar/:hash endpoint bundled under GitLab /-/grafana/
**Root cause:** The /avatar/:hash route URL-decodes the hash before concatenating it into the gravatar fetch URL, allowing injection of extra query parameters (e.g. `d`) that trigger a redirect chain.
**Steps:**
1. Identify Grafana bundled at `/-/grafana/` with route `r.Get("/avatar/:hash", avatarCacheServer.Handler)`.
2. Note hash is URL-decoded then concatenated into `https://secure.gravatar.com/avatar/<hash>?<params>`.
3. Inject `d` param via encoded `%3f`/`%3d` to make gravatar redirect to `i0.wp.com`.
4. Abuse i0.wp.com open redirect: `http://i0.wp.com/google.com/1.bp.blogspot.com/` redirects to `https://google.com/1.bp.blogspot.com`.
5. Point the redirect host at an attacker-controlled redirector to reach arbitrary internal hosts.
6. PoC: `curl "https://dev.gitlab.org/-/grafana/avatar/test%3fd%3dredirect.rhynorater.com%252f1.bp.blogspot.com%252fpoc.rhynorater.com%26cachebust"`
**How found:** Source review of Grafana's avatar route revealed the hash is URL-decoded before being concatenated into the gravatar URL, hinting at parameter injection; then extensive investigation of i0.wp.com's image-hosting redirect behavior uncovered the `1.bp.blogspot.com` open-redirect trick.
**Exploitation:** Unauthenticated attacker sends a crafted /avatar/ request; the server follows the redirect chain (gravatar -> i0.wp.com -> attacker redirector -> target) and returns the fetched response, yielding full-read SSRF against internal services.
**Escalation:** Full-read SSRF can lead to RCE in cloud environments via metadata service misconfigurations.
**Insight:** When a path segment is URL-decoded and concatenated into an outbound URL, try smuggling `?`/`&`/`=` to inject query params; then hunt for open redirects on any host the target fetches from (e.g. gravatar's `d` param) to pivot to arbitrary hosts.

