<?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: XenoVenom</title>
    <description>The latest articles on DEV Community by XenoVenom (@xenovenom).</description>
    <link>https://dev.to/xenovenom</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%2F4097981%2F75b1ad3a-8960-413d-81d6-885da1a6bfb2.png</url>
      <title>DEV Community: XenoVenom</title>
      <link>https://dev.to/xenovenom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xenovenom"/>
    <language>en</language>
    <item>
      <title>How I built a Chrome Extension to intercept Crypto Wallet Drains (EIP-2612 &amp; ERC-20)</title>
      <dc:creator>XenoVenom</dc:creator>
      <pubDate>Mon, 31 Aug 2026 19:03:51 +0000</pubDate>
      <link>https://dev.to/xenovenom/how-i-built-a-chrome-extension-to-intercept-crypto-wallet-drains-eip-2612-erc-20-23ed</link>
      <guid>https://dev.to/xenovenom/how-i-built-a-chrome-extension-to-intercept-crypto-wallet-drains-eip-2612-erc-20-23ed</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2k3wkzku3a5t3st7xecx.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2k3wkzku3a5t3st7xecx.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
If you spend enough time in Web3, you eventually see a friend get their wallet drained. The most frustrating part isn't just the loss of funds; it's the UI.&lt;/p&gt;

&lt;p&gt;When a user encounters a malicious smart contract, standard security tools often throw hex codes at them:&lt;/p&gt;

&lt;p&gt;⚠️ Error: 0x095ea7b3...&lt;/p&gt;

&lt;p&gt;Normal users panic, don't understand the alert, and click "Ignore" anyway. Or worse, they get "alert fatigue" and turn the tool off completely.&lt;/p&gt;

&lt;p&gt;I wanted to solve this "False Sense of Security" problem. So, I built SafeSign Visualizer—an open-source Chrome extension that intercepts malicious transactions before MetaMask opens, and translates them into a "Visual Time-Travel UI" that anyone can understand.&lt;/p&gt;

&lt;p&gt;In this post, I'll walk through the core architecture of how to intercept and decode Web3 scams using Plasmo and React.&lt;/p&gt;

&lt;p&gt;🧠 The Architecture: The "Man-in-the-Middle" Shield&lt;br&gt;
Chrome Extensions live in an "Isolated World." They cannot see the window.ethereum object that MetaMask injects into a webpage.&lt;/p&gt;

&lt;p&gt;To intercept a transaction, we must inject a script into the MAIN world of the page before MetaMask loads, and overwrite the window.ethereum.request function with a Proxy.&lt;/p&gt;

&lt;p&gt;Using Plasmo, this is incredibly clean. We create a content script that runs at document_start:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;import type { PlasmoCSConfig } from "plasmo"export const config: PlasmoCSConfig = {  matches: [""],  run_at: "document_start",  world: "MAIN" // This is the magic key}const intercept = () =&amp;gt; {  if (window.ethereum) {    const originalRequest = window.ethereum.request        // Overwrite the request function    window.ethereum.request = async (args) =&amp;gt; {      // 1. Analyze the transaction      // 2. If bad -&amp;gt; throw error (stops MetaMask)      // 3. If good -&amp;gt; return originalRequest(...)    }  } else {    setTimeout(intercept, 50) // Wait for wallet to load  }}intercept()&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🛡️ Decoding the Scams (Heuristics)&lt;br&gt;
Once we intercept the request, we need to analyze the args.params[0].data to see what the smart contract is actually trying to do.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Unlimited Token Approval (ERC-20)
The most common drain. A site asks you to swap, but the hidden code calls the approve function (0x095ea7b3) with the maximum possible integer (ffffffff...).
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (args.method === "eth_sendTransaction") {
  const data = args.params?.[0]?.data

  if (data.startsWith("0x095ea7b3")) {
    // Extract the amount (last 32 bytes)
    const amountHex = data.slice(74)
    const maxUint = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

    if (amountHex === maxUint) {
       // BLOCK! Scammer is asking for infinite access.
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;The "Invisible" Gasless Drain (EIP-2612)
This is the most dangerous scam right now. Scammers use a fake "Sign-In With Ethereum" button. It costs no gas, so users think it's harmless. But hidden in the eth_signTypedData_v4 payload is a Permit signature.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By signing it, the user gives the scammer a legal off-chain permission slip to drain their USDT later.&lt;/p&gt;

&lt;p&gt;To stop this, we parse the JSON payload of the signature request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (args.method === "eth_signTypedData_v4") {
  const typedData = JSON.parse(args.params[1])

  const isPermit = typedData?.primaryType === "Permit"
  const hasPermitFields = typedData?.message?.spender &amp;amp;&amp;amp; typedData?.message?.value

  if (isPermit || hasPermitFields) {
     // BLOCK! This is a gasless permit drain.
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎨 Visual Storytelling (The UI)&lt;br&gt;
When a scam is detected, we throw an error to stop MetaMask from opening, and we send a window.postMessage to our React Content Script UI to mount a full-screen overlay.&lt;/p&gt;

&lt;p&gt;Instead of technical jargon, we show a timeline of the consequence:&lt;/p&gt;

&lt;p&gt;Now: You click sign.&lt;br&gt;
+2 Seconds: Site gets Unlimited Access.&lt;br&gt;
+10 Seconds: Wallet Drained.&lt;br&gt;
This "Visual Storytelling" approach ensures that non-technical users actually understand why they shouldn't click sign, rather than just ignoring a red warning box.&lt;/p&gt;

&lt;p&gt;🚀 Open Source&lt;br&gt;
I built SafeSign to be 100% free, open-source, and privacy-first. There is no backend, no tracking, and no data collection. All analysis happens locally in the browser.&lt;/p&gt;

&lt;p&gt;If you want to look at the exact code, borrow the interception logic for your own dApp, or install it to protect your own wallet, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/XenoVenom/safesign-visualizer" rel="noopener noreferrer"&gt;💻 GitHub Repository&lt;/a&gt;&lt;br&gt;
&lt;a href="https://tinyurl.com/4t6w7p48" rel="noopener noreferrer"&gt;🌐 Chrome Web Store&lt;/a&gt;&lt;br&gt;
I'd love to hear your feedback on the architecture or any ideas you have for improving the heuristics!&lt;/p&gt;

</description>
      <category>web3</category>
      <category>javascript</category>
      <category>react</category>
      <category>security</category>
    </item>
  </channel>
</rss>
