<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jatin Banga</title>
    <description>The latest articles on DEV Community by Jatin Banga (@jatin_banga_33ba1cfbb9421).</description>
    <link>https://dev.to/jatin_banga_33ba1cfbb9421</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3731388%2F51d660bf-6b0a-4a6c-b273-f44b40c54c6d.png</url>
      <title>DEV Community: Jatin Banga</title>
      <link>https://dev.to/jatin_banga_33ba1cfbb9421</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jatin_banga_33ba1cfbb9421"/>
    <language>en</language>
    <item>
      <title>I Found a Bug That Exposed Private Instagram Posts to Anyone.</title>
      <dc:creator>Jatin Banga</dc:creator>
      <pubDate>Sun, 25 Jan 2026 14:40:12 +0000</pubDate>
      <link>https://dev.to/jatin_banga_33ba1cfbb9421/i-found-a-bug-that-exposed-private-instagram-posts-to-anyone-4eal</link>
      <guid>https://dev.to/jatin_banga_33ba1cfbb9421/i-found-a-bug-that-exposed-private-instagram-posts-to-anyone-4eal</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Verification Requested:&lt;br&gt;
I’m inviting independent security researchers to review the technical analysis, timelines, and artifacts to assess whether the described behavior was possible at the time of testing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;This article was originally published on Medium: &lt;a href="https://medium.com/p/eebb7923f7e3" rel="noopener noreferrer"&gt;I Found a Bug That Exposed Private Instagram Posts to Anyone&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;A 102-day journey through Meta’s bug bounty process&lt;/p&gt;

&lt;p&gt;In October 2025, I discovered a server-side vulnerability in Instagram that allowed completely unauthenticated access to private account posts. &lt;strong&gt;No login required&lt;/strong&gt;. &lt;strong&gt;No follower relationship&lt;/strong&gt;. Just an HTTP request with the right headers.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;This is the story of that disclosure.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Discovery
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Private posts. Full resolution images. Captions. All of it embedded in the HTML response to an unauthenticated request.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The post was there and the CDN links worked. This wasn’t a fluke.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Worked
&lt;/h2&gt;

&lt;p&gt;The exploit was straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send an unauthenticated GET request to &lt;code&gt;instagram.com/&amp;lt;private_username&amp;gt;&lt;/code&gt; with specific mobile headers&lt;/li&gt;
&lt;li&gt;Server returns HTML containing embedded JSON with &lt;code&gt;polaris_timeline_connection&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Extract CDN links from the &lt;code&gt;edges&lt;/code&gt; array
Access private photos with captions directly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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 &lt;br&gt;
response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo of Poc.py&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/VTVdrvAJ28E"&gt;
  &lt;/iframe&gt;


&lt;br&gt;
&lt;em&gt;Video Demonstration: The script extracting CDN links from a private account, followed by the browser successfully loading the full-resolution private image without any authentication.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Poc script exposes private post:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fusg7tuwb1mltsthr30fp.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fusg7tuwb1mltsthr30fp.webp" alt="Script shown in action exposing private post data. Source Video 2 at 0:25 seconds"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Script shown in action exposing private post data. Source &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass/blob/main/network_logs_and_samples/videos.txt" rel="noopener noreferrer"&gt;Video 2&lt;/a&gt; at 0:25 seconds&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Poc script in action for a third party account:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesclqxt2wa3n1xushll5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesclqxt2wa3n1xushll5.png" alt="Source Video 3"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Source &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass/blob/main/network_logs_and_samples/videos.txt" rel="noopener noreferrer"&gt;Video 3&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing Scope
&lt;/h2&gt;

&lt;p&gt;I limited all formal testing to accounts I owned or had explicit permission to test. Out of 7 authorized accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 were vulnerable (~28%) — though given the accidental discovery on a non-authorized account among others, the true rate is likely higher&lt;/li&gt;
&lt;li&gt;5 were not affected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Report
&lt;/h2&gt;

&lt;p&gt;On October 12, 2025, I submitted a detailed report to Meta’s bug bounty program with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full technical explanation&lt;/li&gt;
&lt;li&gt;Proof-of-concept script&lt;/li&gt;
&lt;li&gt;Video demonstration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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 &lt;strong&gt;server-side authorization failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This time, Meta engaged.&lt;/p&gt;




&lt;h2&gt;
  
  
  Back and Forth
&lt;/h2&gt;

&lt;p&gt;Over the next few days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;October 13: Meta asked me to test on their account, &lt;code&gt;2fa_2fa&lt;/code&gt;. The exploit did not work — providing an early clue that this was a conditional bug.&lt;/li&gt;
&lt;li&gt;October 14: Meta requested another vulnerable account. I provided one (with consent): &lt;code&gt;its_prathambanga&lt;/code&gt;. The exploit worked, and I sent video evidence of both manual browser reproduction and the POC script.&lt;/li&gt;
&lt;li&gt;October 15: I sent a detailed analysis explaining the two-part behavior: specific headers trigger a state where the server returns &lt;code&gt;0 followers / 0 following&lt;/code&gt;, and in that state, the private timeline data is incorrectly populated for some accounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraseh30nqwmi1f9tvl0r.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraseh30nqwmi1f9tvl0r.webp" alt="The “Trigger State”: Note the background stats. Despite accessing a private account with multiple followers, the server returns 0 followers / 0 following (highlighted) with a story ring, confirming the session is in a corrupted state.&amp;lt;br&amp;gt;
"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The “Trigger State”: Note the background stats. Despite accessing a private account with multiple followers, the server returns 0 followers / 0 following (highlighted) with a story ring, confirming the session is in a corrupted state.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Silent Patch
&lt;/h2&gt;

&lt;p&gt;On October 16, 2025, I noticed the exploit no longer worked. Every account that was previously vulnerable now returned empty responses.&lt;/p&gt;

&lt;p&gt;Meta had patched it. Silently. Without notification.&lt;/p&gt;

&lt;p&gt;I sent a follow-up asking for confirmation that the vulnerability was fixed.&lt;/p&gt;

&lt;p&gt;No response.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Denial
&lt;/h2&gt;

&lt;p&gt;Eleven days later, on October 27, I received Meta’s official response:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“We are unable to reproduce this issue.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Unable to reproduce — the issue they had just patched.&lt;/p&gt;

&lt;p&gt;I replied pointing out the contradiction: you asked for vulnerable accounts, I provided them, those accounts are now fixed. How is this unreproducible?&lt;/p&gt;

&lt;p&gt;Meta’s response:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“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.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The case was closed as ”&lt;strong&gt;Not Applicable&lt;/strong&gt;.” No acknowledgment.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Missing
&lt;/h2&gt;

&lt;p&gt;Three things stand out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Meta never requested the debug data I offered&lt;/strong&gt;: I offered to provide full network logs with X-FB-Debug headers — everything needed to trace the issue internally. No response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No investigation despite a comparative account list&lt;/strong&gt; : 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No root cause analysis&lt;/strong&gt;: 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.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Evidence
&lt;/h2&gt;

&lt;p&gt;I documented everything with timestamps and integrity verification:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;POC Script&lt;/strong&gt;: Python script that extracted private CDN links&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before / After Screenshots&lt;/strong&gt;: Same request, before and after patch&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Video Evidence&lt;/strong&gt;: 4 timestamped recordings with SHA256 hashes, with historical git commit and push history&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meta Communications&lt;/strong&gt;: Complete PDF archive for all correspondence&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass/tree/main/network_logs_and_samples" rel="noopener noreferrer"&gt;Network Logs, Exposed Link Samples&lt;/a&gt;&lt;/strong&gt;: All headers with samples where the exploit worked, where it did not work and CDN links that were exposed.&lt;/p&gt;

&lt;p&gt;All evidence was committed to &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass" rel="noopener noreferrer"&gt;Git&lt;/a&gt; during the reporting process. The timestamps cannot be fabricated retroactively.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Before &amp;amp; After&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqac0iqay37r7ijcoie9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqac0iqay37r7ijcoie9.webp" alt="Before Private data visible in  raw `polaris_timeline_connection.edges` endraw &amp;lt;br&amp;gt;
"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Before: Private data visible in &lt;code&gt;polaris_timeline_connection.edges&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F901pviukfk70jmkayayp.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F901pviukfk70jmkayayp.webp" alt="After Same request returns empty  raw `edges` endraw  array. Source Video 4"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;After: Same request returns empty &lt;code&gt;edges&lt;/code&gt; array. &lt;br&gt;
Source &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass/blob/main/network_logs_and_samples/videos.txt" rel="noopener noreferrer"&gt;Video 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Really Happened?
&lt;/h2&gt;

&lt;p&gt;I don’t know if this was a cover-up or negligence. Both explanations are concerning.&lt;/p&gt;

&lt;p&gt;What I know is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The vulnerability existed and was documented with video evidence&lt;/li&gt;
&lt;li&gt;Meta asked me to provide vulnerable accounts&lt;/li&gt;
&lt;li&gt;Those exact accounts were patched within 48 hours&lt;/li&gt;
&lt;li&gt;Meta then claimed the issue was unreproducible&lt;/li&gt;
&lt;li&gt;The case was closed without root cause analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Dismissing it with “infrastructure changes” doesn’t inspire confidence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I’m Disclosing
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Details
&lt;/h2&gt;

&lt;p&gt;For those who want to dig deeper:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Github&amp;amp; README&lt;/strong&gt; - &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass" rel="noopener noreferrer"&gt;Overview and evidence links&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TIMELINE.md&lt;/strong&gt; with videos, images - &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass/blob/main/TIMELINE.md" rel="noopener noreferrer"&gt;Complete chronological record&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;poc.py&lt;/strong&gt; - &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass/blob/main/poc.py" rel="noopener noreferrer"&gt;Proof-of-concept script&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;official_communication/&lt;/strong&gt; - &lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass/tree/main/official_communication" rel="noopener noreferrer"&gt;Full Meta correspondence (PDF)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Community Discussions
&lt;/h2&gt;

&lt;p&gt;This disclosure has sparked conversations in the security community. Here are key threads where researchers are reviewing and discussing the findings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;X (Twitter) Thread&lt;/strong&gt;: View the original announcement and community responses.


&lt;iframe class="tweet-embed" id="tweet-2015028650673143840-454" src="https://platform.twitter.com/embed/Tweet.html?id=2015028650673143840"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2015028650673143840-454');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2015028650673143840&amp;amp;theme=dark"
  }





&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Contact info available in the &lt;strong&gt;&lt;a href="https://github.com/jatin-dot-py/instagram-private-bypass" rel="noopener noreferrer"&gt;GitHub README&lt;/a&gt;&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>programming</category>
      <category>cybersecurity</category>
    </item>
  </channel>
</rss>
