In October 2025, I discovered a server-side vulnerability in Instagram that allowed completely unauthenticated access to private account posts. No login required. No follower relationship. Just an HTTP request with the right headers.
Meta silently patched it within 48 hours of receiving my report. Then they closed my case as “Not Applicable” — officially maintaining the bug never existed, despite fixing exactly what I reported.
A 102-day journey through Meta’s bug bounty process. This is the story of that disclosure.
The Discovery
I was building a workflow automation tool for HTTP requests when I stumbled onto something unexpected. While examining Instagram’s mobile web responses, I noticed CDN links being returned for content that shouldn’t have been accessible.
Private posts. Full resolution images. Captions. All of it embedded in the HTML response to an unauthenticated request.
My first instinct was disbelief. I reloaded the page. Ran the request again. Checked if I was somehow authenticated. I wasn’t. The data kept coming back.
I assumed it was a fluke — some kind of caching artifact that would disappear. But it didn’t. After multiple tests on the same account, I realized I needed to verify this properly. So I tested on my own private account: I made a post, waited a few hours, then ran the same request without authentication.
The post was there and the CDN links worked. This wasn’t a fluke.
How It Worked
The exploit was straightforward:
- Send an unauthenticated GET request to `instagram.com/<private_username>` with specific mobile headers
- Server returns HTML containing embedded JSON with `polaris_timeline_connection`
- Extract CDN links from the `edges` array
- Access private photos with captions directly
The server was actively generating this private data for unauthorized requests. This wasn’t a CDN caching issue — Instagram’s backend was failing to check authorization before populating the response.
Demo of Poc.py
Poc script exposes private post:
Press enter or click to view image in full size
Poc script in action for a third party account:
Press enter or click to view image in full size
Testing Scope
I limited all formal testing to accounts I owned or had explicit permission to test. Out of 7 authorized accounts:
- 2 were vulnerable (~28%) — though given the accidental discovery on a non-authorized account, the true rate is likely higher
- 5 were not affected
The vulnerability appeared to be conditional — not all private accounts were exposed. Initial testing suggested a correlation with account age, but the true cause was never determined.
The analysis of authorized testing is accessible here: https://github.com/jatin-dot-py/instagram-private-bypass/blob/main/analysis.json
The Report
On October 12, 2025, I submitted a detailed report to Meta’s bug bounty program with:
- Full technical explanation
- Proof-of-concept script
- Video demonstration
The first report was quickly closed — Meta misinterpreted it as a CDN caching issue (Case Number: 1838087146916736). I immediately filed a second report (Case Number: 1838100803582037) with clearer language emphasizing this was a server-side authorization failure.
This time, Meta engaged.
Back and Forth
Over the next few days:
- October 13: Meta asked me to test on their account, `2fa_2fa`. The exploit did not work — providing an early clue that this was a conditional bug.
- October 14: Meta requested another vulnerable account. I provided one (with consent): `its_prathambanga`. The exploit worked, and I sent video evidence of both manual browser reproduction and the POC script.
- October 15: I sent a detailed analysis explaining the two-part behavior: specific headers trigger a state where the server returns `0 followers / 0 following`, and in that state, the private timeline data is incorrectly populated for some accounts.
The Silent Patch
On October 16, 2025, I noticed the exploit no longer worked. Every account that was previously vulnerable now returned empty responses.
Get Jatin Banga’s stories in your inbox
Join Medium for free to get updates from this writer.
Meta had patched it. Silently. Without notification.
I sent a follow-up asking for confirmation that the vulnerability was fixed.
No response.
The Denial
Eleven days later, on October 27, I received Meta’s official response:
“We are unable to reproduce this issue.”
Unable to reproduce — the issue they had just patched.
I replied pointing out the contradiction: you asked for vulnerable accounts, I provided them, those accounts are now fixed. How is this unreproducible?
Meta’s response:
“The fact that an unreproducible issue was fixed doesn’t change the fact that it was not reproducible at the time. Even if the issue were reproducible, it’s possible that a change was made to fix a different issue and this issue was fixed as an unintended side effect.”
The case was closed as ”Not Applicable.” No acknowledgment.
What’s Missing
Three things stand out:
- Meta never requested the debug data I offered: I offered to provide full network logs with X-FB-Debug headers — everything needed to trace the issue internally. No response.
- No investigation despite a comparative account list : I provided a list showing which accounts were exploitable and which weren’t. This was a ready-made diagnostic dataset for understanding the conditional nature of the bug. No follow-up.
- No root cause analysis: Meta attributed the fix to “infrastructure changes” or “unintended side effect of other changes” — not a targeted fix based on investigation. Without identifying the root cause, there’s no confirmation the underlying issue is truly resolved.
The Evidence
I documented everything with timestamps and integrity verification:
POC Script: Python script that extracted private CDN links
Before / After Screenshots: Same request, before and after patch
Video Evidence: 4 timestamped recordings with SHA256 hashes, with historical git commit and push history
Meta Communications: Complete PDF archive for all correspondence
Network Logs, Exposed Link Samples: All headers with samples where the exploit worked, where it did not work and CDN links that were exposed.
All evidence was committed to Git during the reporting process. The timestamps cannot be fabricated retroactively.
Press enter or click to view image in full size
Press enter or click to view image in full size
What Really Happened?
I don’t know if this was a cover-up or negligence. Both explanations are concerning.
What I know is:
- The vulnerability existed and was documented with video evidence
- Meta asked me to provide vulnerable accounts
- Those exact accounts were patched within 48 hours
- Meta then claimed the issue was unreproducible
- The case was closed without root cause analysis
Instagram serves over a billion users who rely on “private” meaning private. A conditional bug that exposes some accounts but not others is arguably more dangerous than one that affects everyone — it’s harder to detect, harder to diagnose, and harder to confirm as fixed.
Dismissing it with “infrastructure changes” doesn’t inspire confidence.
Why I’m Disclosing
The standard coordinated disclosure window is 90 days. I gave Meta 102 days and multiple escalation attempts. The exploit stopped working on all accounts I tested — though without root cause analysis from Meta, there’s no confirmation the underlying issue is truly resolved.