Local Storage et IndexedDB de Chrome (LevelDB)
2026-05-19 · 3 min
Au-delà des fichiers SQLite, Chrome conserve l'état des applications web
dans des magasins clé-valeur LevelDB. La plupart des enquêteurs les sautent
et passent à côté de la source la plus riche en preuves d'intention sur la
machine. Une identité connectée, un brouillon de message, un jeton OAuth,
l'URL d'un document Drive que l'utilisateur a ouvert : ces données
résident dans Local Storage ou IndexedDB, pas dans History.
Où c'est stocké dans le profil
Local Storage/leveldb/ # window.localStorage par origine
Session Storage/ # session storage par onglet
IndexedDB/<origin>.indexeddb.leveldb/ # bases applicatives structurées
IndexedDB/<origin>.indexeddb.blob/ # gros blobs référencés par le LDB
Chaque entrée est un dossier, pas un fichier unique : CURRENT,
MANIFEST-NNNNNN, un ou plusieurs SSTables *.ldb, et un write-ahead log
*.log. Copiez tout le répertoire ou LevelDB refusera de l'ouvrir.
Le format qu'il faut réellement lire
LevelDB est un arbre LSM. Pour énumérer correctement les clés :
- Lisez
CURRENTpour trouver le manifest actif. - Parcourez
MANIFEST-*pour savoir quels SSTables sont actifs et à quel niveau. - Fusionnez les SSTables actifs avec le WAL
*.log; le dernier écrit l'emporte par clé. - Pour chaque bloc, décompressez Snappy si le trailer l'indique.
Les valeurs nécessitent ensuite un décodage spécifique au format :
- Les clés Local Storage sont
_<origin>\x00<key>. Les valeurs commencent par un marqueur d'encodage d'un octet :0x00UTF-16LE,0x01Latin-1, parfois précédé d'un octet meta. - Session Storage utilise une indirection
namespace -> map -> key. Résolvez via les clés de meta-namespace avant d'extraire les valeurs. - Les valeurs IndexedDB sont encodées en V8 structured-clone. Nombres, chaînes et objets simples se relèvent proprement ; les références cycliques et les typed arrays demandent une gestion attentive.
Les vraies preuves que l'on trouve ici
- Slack, Teams, Discord, Notion : ID utilisateur connecté, ID d'espace de travail, canaux récemment ouverts, brouillons de messages.
- Google Docs / Drive : ID de fichier (la longue partie aléatoire d'une URL Drive), titres des documents récemment modifiés, état de synchronisation.
- VS Code Web / GitHub Codespaces : chemins de fichiers ouverts, noms de dépôts.
- Banque et SSO : jetons JWT avec des revendications encore exploitables (audience, émetteur, expiration, parfois le nom d'utilisateur).
- Portefeuilles crypto : adresses stockées, souvent l'identifiant du portefeuille.
Mises en garde
- Le WAL (
*.log) contient les écritures les plus récentes. Si vous ne copiez que les fichiers*.ldb, vous perdez les dernières minutes d'activité. - La compaction LevelDB peut produire des tombstones pour les clés supprimées qui ressortent malgré tout pendant la fusion. Traitez les NUL inexpliqués dans votre sortie comme des suppressions, pas comme des données.
- Les navigateurs migrent parfois les origines entre magasins LevelDB. Un arrêt propre est plus tolérant ; un plantage en cours de migration peut laisser des données orphelines qui méritent d'être récupérées manuellement.