Architecture technique de l’autoremplissage du gestionnaire de mots de passe
Cette note documente précisément le fonctionnement interne de la chaîne d’autoremplissage de l’application gestionnaireMDP.
L’objectif est double :
- Décrire le pipeline complet — du navigateur jusqu’au déchiffrement local.
- Documenter les limites rencontrées lors d’une version précédente qui n’a jamais été mise en production.
1. Vue d’ensemble architecturale
L’architecture repose sur une séparation stricte entre le navigateur et le système local. Le navigateur ne communique jamais directement avec la base de données.
2. Détection côté navigateur
Fichier : contrib/extension/content_script.js
Le content script :
- Localise le premier
input[type="password"] - Détermine
window.location.origin - Envoie une requête
requestLogins(origin) - Effectue un fallback global si aucun résultat spécifique n’est trouvé
Injection DOM
Une fois la réponse reçue :
- Sélection du premier résultat (après scoring)
- Identification heuristique du champ login
- Injection du login
- Injection du mot de passe dans le champ détecté
- Déclenchement d’événements
inputpour compatibilité avec frameworks frontend
3. Pont Native Messaging
Fichier : contrib/extension/background.js
Responsabilité :
- Écoute les requêtes
requestLogins - Transmet au host natif via :
browser.runtime.sendNativeMessage("com.monapp.nativehost", payload)- Retourne la réponse JSON brute au content script
Le background agit comme un proxy contrôlé entre le navigateur et le service local.
4. Native Host — Accès et déchiffrement
Fichier : contrib/native/monmdp-host.py
Pipeline interne
fetch_all_ciphertexts()→ appeldocker compose ... psql- Récupération des entrées chiffrées
load_session_privkey()decrypt_record_with_privkey()- Attribution d’un score basé sur la correspondance domaine
- Tri décroissant
- Retour JSON au navigateur
5. Modèle de sécurité
- Les identifiants sont stockés chiffrés en base
- La clé privée de session est stockée localement :
~/.local/share/monmdp/session_privkey.b64- Si la clé est absente ou verrouillée :
{ "status": "locked" }Le déchiffrement ne s’effectue qu’après déverrouillage explicite.
6. Version non déployée — Problèmes rencontrés
Avant l’architecture actuelle, une version alternative avait été développée mais jamais mise en production.
6.1 Problème de performance
Le processus initial :
- Déchiffrait un volume trop large d’entrées
- Introduisait une latence perceptible
- Ralentissait l’autoremplissage
L’expérience utilisateur devenait non déterministe.
6.2 Injection incorrecte
Un problème plus critique a été observé :
- Le mot de passe pouvait apparaître brièvement en clair
- Injection parfois effectuée dans un mauvais champ
- Comportement accentué par des frameworks frontend réactifs
Causes probables :
- Heuristiques DOM insuffisamment robustes
- Mauvais timing entre déchiffrement et injection
- Ambiguïtés dans la détection des champs
Ce risque a conduit à suspendre cette implémentation.
7. Analyse rétrospective
À l’époque :
- Développement principalement manuel
- Profilage limité
- Tests automatisés restreints
Je n’avais pas encore expérimenté un développement assisté par agent.
Aujourd’hui, il devient pertinent de revisiter cette implémentation avec :
- Profilage précis du pipeline
- Tests automatisés des heuristiques DOM
- Validation systématique avant injection
- Optimisation du déchiffrement
8. Améliorations envisagées
Performance
- Pré-filtrage en base par domaine
- Déchiffrement paresseux (lazy decrypt)
- Cache mémoire court terme
Robustesse DOM
- Détection multi-formulaire
- Validation stricte des champs avant injection
- Séparation stricte login/password
Sécurité
- Double validation avant injection mot de passe
- Journalisation non sensible
- Tests des cas limites
Conclusion
La chaîne actuelle repose sur :
- Une séparation stricte navigateur / système local
- Un déchiffrement local sous contrôle de clé privée
- Un scoring par domaine pour prioriser les résultats
La version précédente a mis en évidence deux risques majeurs :
- Latence excessive due au déchiffrement massif
- Injection incorrecte pouvant exposer brièvement un secret
Ces limites ont justifié son abandon temporaire.
La prochaine itération devra être :
- Plus rapide
- Plus déterministe
- Plus strictement validée
L’architecture est saine. L’implémentation devra maintenant atteindre le même niveau de rigueur.