<?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: Defyzzz</title>
    <description>The latest articles on DEV Community by Defyzzz (@defyzzz).</description>
    <link>https://dev.to/defyzzz</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%2F3870098%2F2639b112-7ce5-4dd4-9a1d-9eb8e008f6a7.jpeg</url>
      <title>DEV Community: Defyzzz</title>
      <link>https://dev.to/defyzzz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/defyzzz"/>
    <language>en</language>
    <item>
      <title>I Built a Browser Extension That Catches Your Secrets Before AI Does</title>
      <dc:creator>Defyzzz</dc:creator>
      <pubDate>Sat, 11 Apr 2026 10:31:20 +0000</pubDate>
      <link>https://dev.to/defyzzz/i-built-a-browser-extension-that-catches-your-secrets-before-ai-does-136e</link>
      <guid>https://dev.to/defyzzz/i-built-a-browser-extension-that-catches-your-secrets-before-ai-does-136e</guid>
      <description>&lt;p&gt;We all do it. Copy a chunk of code, paste it into ChatGPT, ask "why doesn't this work?" — and accidentally send your AWS keys, database credentials, or a client's email along with it.&lt;/p&gt;

&lt;p&gt;I did it once. I pasted a config file into Claude and realized — three seconds too late — that it contained a production database connection string. Nothing bad happened. But that "oh no" feeling stuck with me.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Nolex&lt;/strong&gt; — a Chrome extension that sits between your clipboard and AI platforms, scanning everything you upload or paste for sensitive data. If it finds something, it shows you exactly what and lets you redact it before sending.&lt;/p&gt;

&lt;p&gt;The key part: &lt;strong&gt;everything runs locally in your browser&lt;/strong&gt;. No servers, no cloud, no telemetry. Your data never leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Is Bigger Than You Think
&lt;/h2&gt;

&lt;p&gt;Every day, millions of developers paste code snippets, configs, logs, and documents into AI chatbots. Most of the time it's fine. But sometimes that snippet contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;sk-proj-...&lt;/code&gt; OpenAI API key&lt;/li&gt;
&lt;li&gt;AWS credentials (&lt;code&gt;AKIA...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;postgresql://user:password@host/db&lt;/code&gt; connection string&lt;/li&gt;
&lt;li&gt;A private SSH key&lt;/li&gt;
&lt;li&gt;A JWT token with user data&lt;/li&gt;
&lt;li&gt;Credit card numbers from test logs&lt;/li&gt;
&lt;li&gt;Phone numbers and emails from customer data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't even notice it's there. The AI platform does — and now your secret lives in someone else's training data, logs, or at minimum their server memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This isn't hypothetical.&lt;/strong&gt; Samsung banned ChatGPT after engineers leaked source code. GitHub found thousands of exposed API keys in public repos — and AI-assisted workflows make this worse, not better.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Nolex Works
&lt;/h2&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%2Fmihvkl7vn644f6zghz9f.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%2Fmihvkl7vn644f6zghz9f.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nolex intercepts two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;File uploads&lt;/strong&gt; — when you drag a &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.json&lt;/code&gt;, &lt;code&gt;.py&lt;/code&gt;, or any other file into ChatGPT/Claude/DeepSeek&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clipboard paste&lt;/strong&gt; — when you Ctrl+V code or text into the chat input&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before the data reaches the AI platform, Nolex scans it against &lt;strong&gt;30+ regex patterns&lt;/strong&gt; covering:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AI Platform Keys&lt;/td&gt;
&lt;td&gt;OpenAI, Anthropic, Google AI, DeepSeek, Hugging Face, Mistral, Cohere, Replicate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud &amp;amp; Infra&lt;/td&gt;
&lt;td&gt;AWS Access/Secret Keys, AWS Session Tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer Tokens&lt;/td&gt;
&lt;td&gt;GitHub PAT, GitHub OAuth, Slack Bot/User Tokens, Discord Bot Tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment&lt;/td&gt;
&lt;td&gt;Stripe Secret/Restricted Keys, Stripe Webhooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databases&lt;/td&gt;
&lt;td&gt;PostgreSQL, MySQL, MongoDB, Redis connection strings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Personal Data&lt;/td&gt;
&lt;td&gt;Email addresses, phone numbers (international + RU format), credit card numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;JWT tokens, SSH/RSA private keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webhooks&lt;/td&gt;
&lt;td&gt;Slack Webhooks, Discord Webhooks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If anything matches, you see an interactive dialog:&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%2F1qfyk4x10ogjuwkp28r2.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%2F1qfyk4x10ogjuwkp28r2.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each finding is highlighted in the text preview. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See exactly what was detected and where&lt;/li&gt;
&lt;li&gt;Click on any finding to jump to its location in the text&lt;/li&gt;
&lt;li&gt;Choose which findings to redact and which to keep&lt;/li&gt;
&lt;li&gt;Replace sensitive values with safe placeholders like &lt;code&gt;***AWS_KEY_REDACTED***&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cancel the upload entirely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If nothing suspicious is found — the file or paste goes through silently. Zero friction when there's nothing to worry about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: Why Local-First Matters
&lt;/h2&gt;

&lt;p&gt;I considered building a SaaS. Backend API, user accounts, cloud scanning. It would've been easier to monetize.&lt;/p&gt;

&lt;p&gt;But think about it: would you send your API keys to &lt;em&gt;another&lt;/em&gt; cloud service just to check if you're about to send your API keys to a cloud service? The irony would be painful.&lt;/p&gt;

&lt;p&gt;So Nolex runs entirely in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────┐
│           Your Browser              │
│                                     │
│  ┌──────────┐    ┌──────────────┐   │
│  │ You paste │───▶│ content.js   │   │
│  │ or upload │    │ (bridge)     │   │
│  └──────────┘    └──────┬───────┘   │
│                         │           │
│                  ┌──────▼───────┐   │
│                  │ interceptor  │   │
│                  │ (fetch/XHR   │   │
│                  │  monkey-patch│   │
│                  └──────┬───────┘   │
│                         │           │
│                  ┌──────▼───────┐   │
│                  │ detector.js  │   │
│                  │ (30+ regex)  │   │
│                  └──────┬───────┘   │
│                         │           │
│               findings? │           │
│              ┌──────────┼────────┐  │
│              │ yes       │ no    │  │
│       ┌──────▼──────┐   │       │  │
│       │  dialog.js  │   │       │  │
│       │ (review UI) │   │       │  │
│       └─────────────┘   │       │  │
│                   ┌─────▼─────┐ │  │
│                   │ Send as-is│ │  │
│                   └───────────┘ │  │
└─────────────────────────────────┘  │
                                     │
              ❌ Nothing leaves here  │
─────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extension uses Chrome's Manifest V3 with only two permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;storage&lt;/code&gt; — to save your settings locally&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;host_permissions&lt;/code&gt; — to intercept requests on AI platform pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;code&gt;tabs&lt;/code&gt;, no &lt;code&gt;activeTab&lt;/code&gt;, no &lt;code&gt;scripting&lt;/code&gt;. Minimal attack surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Interception Trick
&lt;/h3&gt;

&lt;p&gt;The interesting technical challenge was intercepting file uploads &lt;em&gt;before&lt;/em&gt; they reach the server. AI platforms use &lt;code&gt;fetch()&lt;/code&gt; or &lt;code&gt;XMLHttpRequest&lt;/code&gt; to send data. Nolex monkey-patches both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalFetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Extract file from request body&lt;/span&gt;
    &lt;span class="c1"&gt;// Scan with detector.js&lt;/span&gt;
    &lt;span class="c1"&gt;// If findings → show dialog, wait for user decision&lt;/span&gt;
    &lt;span class="c1"&gt;// If clean → pass through to original fetch&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;originalFetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&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;For clipboard, it hooks into the &lt;code&gt;paste&lt;/code&gt; event before the AI platform's own handler processes it.&lt;/p&gt;

&lt;p&gt;This means Nolex works on &lt;strong&gt;any&lt;/strong&gt; website — not just ChatGPT. If a site uses &lt;code&gt;fetch&lt;/code&gt; to upload files, Nolex can scan them. It works on Claude, DeepSeek, Gemini, Copilot, and any other AI tool that runs in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart Constructor: Build Your Own Patterns
&lt;/h2&gt;

&lt;p&gt;The built-in 30+ patterns cover common cases, but every team has unique secrets. Internal service tokens, custom API key formats, employee IDs — things no generic tool would know about.&lt;/p&gt;

&lt;p&gt;That's why Nolex includes a &lt;strong&gt;Smart Constructor&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%2Fo75eqp1hqe9zwmynan3q.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%2Fo75eqp1hqe9zwmynan3q.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write custom regex patterns with a name and replacement template&lt;/li&gt;
&lt;li&gt;Test them against sample text in real-time&lt;/li&gt;
&lt;li&gt;Group patterns into categories&lt;/li&gt;
&lt;li&gt;Import/Export pattern sets as JSON — share with your team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is especially useful for security teams who want to enforce company-wide policies. Create a pattern set, export it, distribute to the team.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Coming: AI-Powered Detection
&lt;/h2&gt;

&lt;p&gt;Regex is great for structured secrets — API keys have predictable formats, emails follow RFC 5322, credit cards pass the Luhn algorithm. But what about &lt;em&gt;unstructured&lt;/em&gt; sensitive data?&lt;/p&gt;

&lt;p&gt;Think about this scenario: you paste a support ticket into ChatGPT to draft a response. The ticket contains:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Customer John Smith (&lt;a href="mailto:john.smith@company.com"&gt;john.smith@company.com&lt;/a&gt;) reported that the payment from card ending 4242 failed at our London office on Jan 15..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Regex catches the email and maybe the card fragment. But what about "John Smith"? "London"? The fact that this is a real person's real support ticket?&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Named Entity Recognition (NER)&lt;/strong&gt; comes in — and it's what we're building next for Nolex Pro.&lt;/p&gt;

&lt;h3&gt;
  
  
  How NER Works in the Browser
&lt;/h3&gt;

&lt;p&gt;We're using &lt;strong&gt;Transformers.js&lt;/strong&gt; — a JavaScript port of Hugging Face's Transformers library — to run a multilingual BERT model directly in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model: bert-base-multilingual-cased-ner-hrl
Size: ~710MB (quantized, cached after first load)
Languages: 100+ (English, Russian, German, French, Chinese...)
Categories: Person, Location, Organization, Miscellaneous
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model runs entirely client-side using WebAssembly and WebGL. No API calls. No server. Your text never leaves your browser — just like the regex engine.&lt;/p&gt;

&lt;p&gt;Here's what the pipeline looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw text → Strip HTML/XML tags
         → Normalize UPPERCASE → Title Case
         → Split into 200-char chunks (BERT limit)
         → Run NER on each chunk
         → Merge B-/I- tokens into entities
         → Deduplicate substrings
         → Map back to original text positions
         → Show in dialog alongside regex findings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One fun challenge: &lt;strong&gt;BERT completely ignores UPPERCASE text&lt;/strong&gt;. Feed it "JOHN SMITH" and it returns nothing. Feed it "John Smith" and it gets 99% confidence. So we normalize case before analysis but display the original text in the dialog.&lt;/p&gt;

&lt;p&gt;Another: BERT's tokenizer splits words into subwords. "Yovovich" becomes &lt;code&gt;"Yovo"&lt;/code&gt; + &lt;code&gt;"##vich"&lt;/code&gt;. The &lt;code&gt;##&lt;/code&gt; prefix means "continuation of previous word" — we merge them back during post-processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  PDF Document Scanning
&lt;/h3&gt;

&lt;p&gt;We're also adding &lt;strong&gt;PDF scanning&lt;/strong&gt; — extract text from uploaded PDFs using Mozilla's pdf.js, then run both regex and NER on the content:&lt;/p&gt;

&lt;p&gt;PDFs are tricky because pdf.js returns text items in PDF &lt;em&gt;object&lt;/em&gt; order, not reading order. A two-column layout might return all of column 2 before column 1. We sort by Y-coordinate (top to bottom) then X-coordinate (left to right) to reconstruct the natural reading flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;p&gt;Since publishing on the Chrome Web Store in March 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;30+ detection patterns&lt;/strong&gt; covering 8 categories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero data sent&lt;/strong&gt; to any server, ever&lt;/li&gt;
&lt;li&gt;Works on &lt;strong&gt;any website&lt;/strong&gt; that uses fetch/XHR&lt;/li&gt;
&lt;li&gt;Extension size: &lt;strong&gt;~150KB&lt;/strong&gt; (without Pro features)&lt;/li&gt;
&lt;li&gt;Scan time: &lt;strong&gt;&amp;lt; 50ms&lt;/strong&gt; for regex, &lt;strong&gt;1-3 seconds&lt;/strong&gt; for NER (first load: ~30s for model download)&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%2Fp0a4jweb03uq09gget78.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%2Fp0a4jweb03uq09gget78.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chrome Web Store&lt;/strong&gt;: &lt;a href="https://chromewebstore.google.com/detail/nolex/chebnmpkokgdhdcmlfooilohcanlpppp" rel="noopener noreferrer"&gt;Install Nolex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Defyzzz/nolex" rel="noopener noreferrer"&gt;github.com/Defyzzz/nolex&lt;/a&gt; (MIT License)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://getnolex.com" rel="noopener noreferrer"&gt;getnolex.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://nolex.gitbook.io/nolex-docs" rel="noopener noreferrer"&gt;nolex.gitbook.io/nolex-docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've ever had that "oh no" moment after pasting something into an AI chatbot — this is for you.&lt;/p&gt;

</description>
      <category>nolex</category>
      <category>javascript</category>
      <category>privacy</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
