DEV Community

Joshua Ofamba
Joshua Ofamba

Posted on • Originally published at Medium on

7 Web3 Security Mistakes Even Experienced Users Are Still Making

You know not to share your seed phrase. You use a hardware wallet. You’ve read the horror stories. And yet the most costly attacks in DeFi keep hitting people who thought they’d covered the basics. Here’s what you’re probably still getting wrong.

Glowing blocks — A blockchain!

Today’s exploits happen in the gap between what you think you’re approving and what actually executes. From compromised frontends to hidden permissions in ‘gasless’ signatures, the goal is to make a malicious transaction look like normal ones. If an attacker can gain your authorization, they don’t need your password.

What follows are seven mistakes that consistently turn up in post-mortems, across wallets of every size. Some are operational habits. Some are knowledge gaps. All of them are fixable today.

1. You’re Using a Single Wallet for Everything

A single address accumulating six months of on-chain activity is a dossier. Every protocol you’ve interacted with, every approval you’ve granted, every NFT mint you’ve participated in is permanently visible. This is not inherently dangerous, but combining your main holding wallet with your active trading wallet, your test wallet, and your airdrop-farming wallet turns a manageable risk surface into an enormous one.

The more consequential problem is address poisoning. An attacker monitors your transaction history, then generates a vanity address that shares the first four and last six characters of a wallet you regularly send to. They send you a zero-value transfer from that address. You later copy-paste from your transaction history rather than your address book, and funds go to an address you’ve never controlled. This attack is low-effort, has no on-chain prevention mechanism, and works precisely because experienced users move fast and rely on visual shortcuts.

Real-world impact

Address poisoning attacks have been responsible for multi-million dollar losses in 2023 and 2024, including a well-documented case where a trader lost $68M in WBTC by copying a poisoned address from their own transaction history. Speed is the attacker’s ally here.

The fix

Maintain at least three distinct address buckets:

  • Cold vault (hardware wallet): used strictly for long-term storage and never interacts with smart contracts.
  • Trading wallet (hot wallet): handles routine DeFi activity and serves as the operational wallet.
  • Dev / experimental wallet : isolated environment for unaudited protocols, new deployments, or testnet spillover.

Funds should never move directly between the cold vault and the experimental wallet. Instead, route transfers through the trading wallet to introduce a deliberate, manual checkpoint.

While verifying full addresses character-by-character is often impractical, you can reduce risk by using tools like MetaMask’s address book rather than copy-pasting from history.

2. You’ve Never Audited Your Token Approvals

Crypto portfolio image


Unlimited token approvals accumulate silently. Most wallets don’t show them proactively.

When you approve a protocol to spend your tokens, that approval persists indefinitely unless you revoke it. Every decentralized application (dApp) interaction you’ve completed over the past two years has likely left at least one open approval. Some of those protocols have since been compromised, abandoned, or had their contracts upgraded by a multisig you have no visibility into.

The attack vector is straightforward: a protocol you approved 18 months ago gets exploited. The attacker drains every wallet with an outstanding approval, not just current users. You haven’t touched that protocol in over a year, but your approval is still live. This is not a theoretical risk; it has driven the majority of DeFi drain events on record.

Here’s JavaScript code using ethers.js to help you check outstanding approvals:

const { ethers } = require("ethers");

// Minimal ERC-20 ABI — allowance function only
const ERC20_ABI = [
  "function allowance(address owner, address spender) view returns (uint256)"
];

async function checkApproval(tokenAddress, ownerAddress, spenderAddress, provider) {
  const contract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
  const allowance = await contract.allowance(ownerAddress, spenderAddress);

  if (allowance.eq(ethers.constants.MaxUint256)) {
    console.warn(`⚠ Unlimited approval active for spender: ${spenderAddress}`);
  } else if (allowance.gt(0)) {
    console.log(`Allowance: ${ethers.utils.formatUnits(allowance, 18)} tokens`);
  } else {
    console.log("No approval outstanding.");
  }
}
Enter fullscreen mode Exit fullscreen mode

The fix

Run a full approval audit using Revoke.cash across every chain you’ve been active on. Revoke anything you don’t actively use today. Going forward, prefer protocols that use exact-amount approvals over unlimited ones, and consider using a wallet interface that surfaces active approvals in-session, like Rabby.

3. You’re Broadcasting Transactions Without MEV Protection

MEV (Maximal Extractable Value) is not an abstract protocol-level concern. It hits you directly every time you execute a swap on a public mempool without protection. The most common form you’ll encounter is the sandwich attack: a bot detects your pending transaction, front-runs it to push the price, lets your trade execute at the inflated price, then back-runs to pocket the difference. Your slippage tolerance is not a defence — it’s the parameter the bot calibrates against.

On a large swap, the extracted value is often invisible to you because it sits inside your slippage allowance. On smaller trades, you simply receive fewer tokens than you should. It is a persistent, automated tax on every unprotected transaction.

Here’s a sample JSON-RPC config using Flashbots Protect RPC (use on MetaMask or any EVM wallet):

// Add as a custom network in MetaMask > Settings > Networks
{
  "networkName": "Ethereum (Flashbots Protect)",
  "rpcUrl": "https://rpc.flashbots.net",
  "chainId": 1,
  "symbol": "ETH",
  "blockExplorer": "https://etherscan.io"
}
// Transactions are routed privately to block builders,
// bypassing the public mempool entirely.
Enter fullscreen mode Exit fullscreen mode

The fix

Switch your Ethereum RPC to Flashbots Protect for any transaction above your personal threshold for acceptable loss. Transactions sent through this endpoint are routed privately and never exposed to the public mempool. On other EVM chains, check whether an equivalent private RPC service exists; most major L2s now offer one.

4. You’re Signing Permits Without Reading Them

Image depicting security boundaries


Hardware wallets protect your keys. They don’t protect you from signing a malicious permit.

EIP-2612 permit signatures are gasless off-chain approvals that let a smart contract spend your tokens without a prior on-chain approval transaction. They are widely used by dApps to improve UX. They are also the primary attack vector used by modern wallet drainers, because a permit signature looks like a benign off-chain message to most wallet interfaces, and users sign them reflexively.

When a malicious site asks you to “sign to verify ownership” or “connect to claim your airdrop,” what it may actually be requesting is a permit signature granting unlimited spending rights to an attacker-controlled address. Your hardware wallet won’t stop this. The keys are yours. The signature is yours. The authorisation is legitimate. The target just happens to be an attacker.

What to check before signing any off-chain message.

Look for these fields in the raw signature data your wallet surfaces:

  • spender  — is this an address you recognise?
  • value  — is this scoped to a specific amount, or is it MaxUint256 ?
  • deadline  — when does this authorisation expire?
  • domain.verifyingContract  — does this match the token contract you’re interacting with?

The fix

Use a wallet that decodes and displays permit parameters in human-readable form before you sign. Rabby and recent versions of MetaMask have improved this significantly. Treat any off-chain signature request with the same level of scrutiny as an on-chain approval. If a site is asking you to sign something and you can’t read the fields clearly, you don’t sign it.

5. You Trust the Frontend, Not the Contract

Supply chain attacks against Web3 frontends have become one of the most effective vectors in the space precisely because technically sophisticated users let their guard down on the interface layer. The assumption is that the smart contract is the attack surface, and the UI is just a convenience. This couldn’t be further from the truth.

In a supply chain attack, an attacker compromises a third-party library or CDN that a dApp frontend loads at runtime. The injected script intercepts your transaction parameters and silently modifies the recipient address or contract call before it reaches your wallet. The confirmation your wallet shows you looks legitimate. The transaction it signs does not go where you think it does. Notable examples include compromised versions of the Ledger Connect Kit in late 2023, which briefly affected multiple major dApp frontends simultaneously.

The fix

Build the habit of verifying the contract address in any transaction your wallet surfaces before confirming, even on protocols you use regularly. Bookmark dApp URLs directly rather than navigating via search results or links in Discord. Keep your browser extensions minimal — wallet extensions with broad page permissions can be compromised too. For large transactions, consider interacting directly with a verified contract on Etherscan rather than through a frontend at all.

6. You Have No Recovery Plan That Doesn’t Involve Your Seed Phrase

Seed phrase for crypto wallet


Photo by rc.xyz NFT gallery on Unsplash

The standard advice — write your seed phrase on metal, store it in two locations, tell no one — is correct as far as it goes. The problem is that it treats recovery as a pure physical security problem. What it doesn’t address is the scenario where the seed phrase itself becomes the attack surface: coercion, inheritance, incapacitation, or the simple reality that the person most likely to access your cold storage in an emergency is also the person you’d want to have access to your funds.

Social recovery, formalised in ERC-4337 account abstraction, separates custody from recovery by letting you designate a set of trusted addresses as guardians. If you lose access, a threshold of guardians can collectively authorise a recovery to a new key. No single point of failure. No seed phrase crossing a network. No trusting one person with everything.

The fix

If you are managing a meaningful amount of value, migrate to or experiment with a smart contract wallet that supports social recovery — Safe (formerly Gnosis Safe) with a multisig setup is the current production-grade standard. For a more personal workflow, wallets implementing ERC-4337 like Ready (Formerly Argent) offer social recovery without requiring all guardians to be co-signers. Pair this with a clearly documented but seed-phrase-free recovery procedure that a trusted person can execute without your direct involvement.

7. Your Dev Environment and Personal Wallet Share an Ecosystem

This is the mistake most commonly made by builders who are also investors, which is a significant portion of the advanced DeFi user base. You’re testing an integration, so you clone a repo, runnpm install, and spin up a local fork. One of the dependencies in that repo has been compromised via a typosquatted package name or a maintainer account takeover. The malicious package scans your environment for private keys, seed phrases, and browser-accessible wallet storage. It finds the MetaMask profile in your browser's user data directory because you use the same machine for development and DeFi.

This is not a contrived scenario. The npm ecosystem has seen a significant increase in targeted crypto-relatedmalicious packages since 2022.

Minimum viable separation

  • Dedicated browser profile (or separate browser) exclusively for DeFi — no development extensions installed
  • Hardware wallet for all meaningful transactions, even when it’s slower
  • Development work is done in a virtual machine (VM) or on a separate physical device if the value at risk justifies it
  • Never import a private key into a hot wallet on a machine used for development

The fix

Treat your development environment and your DeFi environment as separate security perimeters with no shared credentials. At minimum, use separate browser profiles with separate MetaMask instances and separate seed phrases. For anything beyond experimental funds, use a hardware wallet whose signing device never connects to your development machine. The friction is low. The risk reduction is substantial.

Conclusion

None of these mistakes requires exceptional technical sophistication to exploit. They require patience, on-chain data analysis, and the well-founded assumption that busy, technically literate users cut corners. The consistent theme across all seven is that experience creates confidence, and confidence creates exposure. The users losing the most money in DeFi today are not beginners who don’t know better — they’re people who thought they already did.

Fixing all seven of these at once is a half-day of work. Pick the ones that apply to you and start there. The attacker’s cost is near zero. Your cost of prevention is not.

Top comments (0)