<?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: Tuna Ergünay</title>
    <description>The latest articles on DEV Community by Tuna Ergünay (@tuna_ergnay_d1a1a5bf2f10).</description>
    <link>https://dev.to/tuna_ergnay_d1a1a5bf2f10</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4118211%2F027895ee-b361-4594-8094-3de6268d64bf.png</url>
      <title>DEV Community: Tuna Ergünay</title>
      <link>https://dev.to/tuna_ergnay_d1a1a5bf2f10</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tuna_ergnay_d1a1a5bf2f10"/>
    <language>en</language>
    <item>
      <title>I shipped a Chrome extension, then found a permission bug and a hidden analytics call in the same week</title>
      <dc:creator>Tuna Ergünay</dc:creator>
      <pubDate>Wed, 09 Sep 2026 21:35:01 +0000</pubDate>
      <link>https://dev.to/tuna_ergnay_d1a1a5bf2f10/i-shipped-a-chrome-extension-then-found-a-permission-bug-and-a-hidden-analytics-call-in-the-same-5adi</link>
      <guid>https://dev.to/tuna_ergnay_d1a1a5bf2f10/i-shipped-a-chrome-extension-then-found-a-permission-bug-and-a-hidden-analytics-call-in-the-same-5adi</guid>
      <description>&lt;h2&gt;
  
  
  The problem I was scratching
&lt;/h2&gt;

&lt;p&gt;Every time I was debugging a web app, the same friction kept happening: I'd&lt;br&gt;
see a request in Chrome DevTools' Network tab, and to actually test a&lt;br&gt;
variation of it — a different header, a different body, a different query&lt;br&gt;
param — I had to copy it out to Postman or Insomnia, paste it in, re-add&lt;br&gt;
auth headers, and lose all the DevTools context in the process. Small&lt;br&gt;
friction, but it happened a dozen times a day.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Network Sniper&lt;/strong&gt;, a Chrome extension that puts an editable,&lt;br&gt;
resend-capable request panel directly inside DevTools. Capture a request,&lt;br&gt;
edit it in place, hit resend, and see a diff between the old and new&lt;br&gt;
response — no context switch.&lt;/p&gt;

&lt;p&gt;It's local-first by design: no telemetry, no cloud sync, sensitive headers&lt;br&gt;
masked by default. That promise turned out to be more important than I&lt;br&gt;
expected, for reasons I'll get to.&lt;/p&gt;
&lt;h2&gt;
  
  
  Launch day: smaller than I hoped, which taught me something
&lt;/h2&gt;

&lt;p&gt;I posted a Show HN. It didn't hit the front page — under 10 upvotes, a&lt;br&gt;
handful of comments. In the first few hours I got about 15 installs, then&lt;br&gt;
growth flattened out almost completely. If you're benchmarking your own&lt;br&gt;
launch: don't assume a Show HN that doesn't take off means the product is&lt;br&gt;
bad. It might just mean the post didn't catch the algorithm's attention&lt;br&gt;
that hour. I posted on a Wednesday; in hindsight I'd try a different day&lt;br&gt;
and spend more time on the title.&lt;/p&gt;

&lt;p&gt;The bigger lesson came from what happened &lt;em&gt;after&lt;/em&gt; launch, not the launch&lt;br&gt;
numbers themselves.&lt;/p&gt;
&lt;h2&gt;
  
  
  Surprise #1: I accidentally asked for way too much permission
&lt;/h2&gt;

&lt;p&gt;To support resending requests to any API the user is debugging (which by&lt;br&gt;
definition could be &lt;em&gt;any&lt;/em&gt; origin — that's the whole point of the tool), my&lt;br&gt;
first shipped version declared:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"host_permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*://*/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This works, technically. It also means Chrome shows every installer a&lt;br&gt;
scary warning: &lt;em&gt;"Read and change all your data on all websites."&lt;/em&gt; For a&lt;br&gt;
tool whose entire pitch is "trustworthy, local-first, minimal," that's a&lt;br&gt;
bad first impression — and it's exactly the kind of thing a careful&lt;br&gt;
reviewer (or a future acquirer, if you're building to eventually sell a&lt;br&gt;
side project) will flag immediately.&lt;/p&gt;

&lt;p&gt;The fix was to stop asking for broad access up front, and instead request&lt;br&gt;
permission for a specific origin only when the user actually tries to&lt;br&gt;
resend a request to it:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"optional_host_permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*://*/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// only requested at the moment of use, scoped to the exact origin&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;granted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;origins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;targetOriginPattern&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Approved origins get cached for the session so the user isn't re-prompted&lt;br&gt;
every time. The install-time warning disappeared completely. Lesson: if&lt;br&gt;
your extension needs broad &lt;em&gt;capability&lt;/em&gt;, that doesn't mean it needs broad&lt;br&gt;
&lt;em&gt;permission&lt;/em&gt; — request narrowly, and only when the user's action actually&lt;br&gt;
requires it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Surprise #2: the "zero telemetry" tool had a Google Analytics property
&lt;/h2&gt;

&lt;p&gt;This one stung more. A few days after launch, I was checking install&lt;br&gt;
numbers and ended up looking at a Google Analytics real-time dashboard&lt;br&gt;
that was, unmistakably, tied to my extension's own ID — active users,&lt;br&gt;
country breakdown, the works. For a project whose README and public launch&lt;br&gt;
comment both said "zero telemetry, nothing leaves the browser," that's not&lt;br&gt;
a small inconsistency.&lt;/p&gt;

&lt;p&gt;I did a full audit: grep'd the entire codebase and build output for any&lt;br&gt;
analytics SDK, tracking domain, or beacon call. Found nothing in the&lt;br&gt;
runtime code. Loaded the actual packaged extension in a real Chrome&lt;br&gt;
profile, pointed it at a live API, and watched the network traffic for a&lt;br&gt;
sustained window. Zero requests to any analytics domain — every outbound&lt;br&gt;
request went exactly where the user told it to go.&lt;/p&gt;

&lt;p&gt;The likely explanation: Chrome Web Store's own Developer Dashboard lets&lt;br&gt;
you optionally link a Google Analytics property to track your &lt;em&gt;store&lt;br&gt;
listing page&lt;/em&gt; views — a completely separate thing from the extension's&lt;br&gt;
runtime behavior. It's easy to conflate "traffic to my listing" with&lt;br&gt;
"telemetry from my extension," and I did, for a few uncomfortable hours.&lt;/p&gt;

&lt;p&gt;I still added a regression test that scans the entire source tree and&lt;br&gt;
build output for analytics domains and SDK signatures, plus a comment at&lt;br&gt;
the top of the manifest and entry files saying, bluntly, &lt;em&gt;don't add&lt;br&gt;
tracking here&lt;/em&gt;. Not because I found a violation, but because "I was pretty&lt;br&gt;
sure it was fine" isn't the bar I want for a tool whose whole pitch is&lt;br&gt;
trust.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where it stands now
&lt;/h2&gt;

&lt;p&gt;Network Sniper is live, permission-minimal, and — as far as a real,&lt;br&gt;
instrumented live-browser test can show — genuinely telemetry-free. Growth&lt;br&gt;
is slow and mostly self-inflicted right now (a quiet Show HN, a Reddit post&lt;br&gt;
caught by a spam filter I'm still waiting on mods to review), which is its&lt;br&gt;
own lesson: shipping the product is maybe 30% of the work, and I&lt;br&gt;
underestimated the rest.&lt;/p&gt;

&lt;p&gt;If you debug APIs and have felt the Postman-copy-paste friction, I'd&lt;br&gt;
genuinely appreciate you trying it and telling me what's missing:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://chromewebstore.google.com/detail/network-sniper/ompgdflcnpfkpfoeappidbhekeifhmpe?authuser=0&amp;amp;amp%3Bhl=tr" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2F1vdlg5MCEcQvkHS8Vwe_cb5XDBUPa4Ot3tkazikfrc2L9gPLnyqFMKEI_-Ua6idFgHvGrS_copLJm4Akx7Q5IGXK%3Ds128-rj-sc0x00ffffff" height="128" class="m-0" width="128"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://chromewebstore.google.com/detail/network-sniper/ompgdflcnpfkpfoeappidbhekeifhmpe?authuser=0&amp;amp;amp%3Bhl=tr" rel="noopener noreferrer" class="c-link"&gt;
            Network Sniper - Chrome Web Store
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            DevTools network inspector, editor, and resend client with environment variables and local-first storage.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fssl.gstatic.com%2Fchrome%2Fwebstore%2Fimages%2Ficon_48px.png" width="48" height="48"&gt;
          chromewebstore.google.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;It's free, Manifest V3, and — now provably — doesn't phone home.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>extensions</category>
    </item>
  </channel>
</rss>
