# BugBounty | A Simple SSRF

Desktop chat client's URL preview feature fetched attacker URLs server-side and executed JS, enabling SSRF to internal hosts and full internal content exfiltration.

- Payout: unconfirmed
- Severity: high
- Program: -
- Credited: Jinone
- Disclosed: 2019-11-05
- Write-up quality: 6/10
- Original: https://jinone.github.io/bugbounty-a-simple-ssrf/
- Library page: https://bugbountylibrary.com/r/blog%3Ajinone-github-io-bugbounty-a-simple-ssrf
- Tags: domain:desktop impact:data-leak impact:internal-access kind:bounty platform:blog sev:high tech:chromium technique:chained technique:recon vuln:ssrf vuln:xss

**Target:** macOS desktop chat client URL preview / link unfurling service
**Root cause:** The URL preview backend fetched arbitrary user-supplied URLs using a headless browser (browser UA) without restricting internal addresses, and rendered/executed attacker JavaScript in that context.
**Steps:**
1. Send a URL in chat and observe preview returns page title/favicon, fetched with a browser User-Agent
2. Point URL at own server to confirm server-side fetch and UA
3. Try `http://127.0.0.1`, `https://127.0.0.1`, `file://etc/passwd`, common internal IPs — no effect
4. Brute-force subdomains / use asset discovery to find an internal IP that responds
5. Host HTML with `<script>` doing synchronous `XMLHttpRequest` GET to internal URL and POST result to attacker PHP logger
6. Read save.txt (or Burp Collaborator) and URL-decode to recover full internal content
7. If SOP blocks, use DNS-rebinding (ByP-SOP) to bypass
**How found:** After web asset testing, pivoted to the macOS client; noticed chat link previews fetched URLs with a browser UA, hypothesized server-side fetch, confirmed via own server, then hunted for reachable internal IPs via subdomain brute force and asset discovery.
**Exploitation:** Attacker sends a crafted URL in chat; the preview service loads it in a browser context, executes the embedded JS which reads internal endpoints via XHR (SOP not enforced) and exfiltrates responses to an attacker-controlled PHP endpoint via POST.
**Escalation:** Chained JS execution in the preview renderer with XHR to reach arbitrary internal hosts; DNS-rebinding suggested to defeat SOP when needed.
**Insight:** Link-preview/unfurl features in desktop and chat clients often run a headless browser server-side; test whether it executes JS and whether XHR from that context reaches internal hosts, and enumerate internal IPs via subdomain/asset discovery when localhost is filtered.
