The Phantom Extension: Backdooring chrome through uncharted pathways
Le renforcement progressif de la sécurité des éléments clés de Windows, comme LSASS, a poussé les attaquants à chercher d’autres vecteurs d’intrusion. Parmi eux, les navigateurs web sont devenus des cibles privilégiées, car ils représentent désormais la principale porte d’entrée aux données sensibles et aux services cloud des entreprises. De nombreux secrets, tels que les tokens et identifiants, transitent via les navigateurs, et leur compromission peut offrir aux attaquants un accès étendu à l’organisation. Cet article présente une technique peu connue permettant de compromettre les navigateurs basés sur Chromium dans les environnements Windows en forçant le chargement d’extensions arbitraires. Lorsqu’elle est appliquée avec succès, cette méthode conduit à une compromission totale du navigateur.
Vous souhaitez améliorer vos compétences ? Découvrez nos sessions de formation ! En savoir plus
Introduction
Les extensions Chromium sont des modules qui permettent aux utilisateurs de personnaliser et d’enrichir leur expérience de navigation. Construites avec les mêmes technologies que les pages web que nous consultons au quotidien (HTML, CSS et JavaScript), elles interagissent avec le navigateur au travers d’un ensemble d’API bien défini. Grâce à ces mécanismes, les extensions peuvent introduire de nouvelles fonctionnalités, modifier le contenu ou le comportement des pages existantes, ou encore s’intégrer de manière transparente à des services tiers. Leurs usages vont des outils de productivité aux bloqueurs de publicités, en passant par des intégrations avancées pensées pour les développeurs et les utilisateurs expérimentés.
Aujourd’hui, le navigateur web a largement dépassé son rôle initial d’outil d’accès à l’information : il est devenu une véritable plateforme de travail, comparable à un système d’exploitation allégé. Ce rôle central en fait naturellement une cible de choix pour les attaquants, ce qui souligne d’autant plus l’importance de renforcer sa sécurité. Nos recherches, initiées sur la version 130 de Chromium et toujours valides jusqu’à la dernière mouture disponible au moment de la rédaction, présentent une technique de backdoor et de post‑exploitation. En tirant parti d’une simple primitive d’écriture sur disque, il devient possible d’installer silencieusement des extensions personnalisées sur des navigateurs basés sur Chromium déployés dans des environnements Windows.
Anatomie d'une extension Chromium
Une extension de navigateur est composée de plusieurs éléments clés qui en définissent la structure, le comportement et les capacités :
- manifest.json : il s’agit du fichier de configuration central de toute extension Chromium. Il fournit les métadonnées essentielles, comme le nom de l’extension, sa version et ses permissions, et spécifie quels scripts exécuter dans quels contextes (par exemple, scripts d’arrière‑plan ou scripts de contenu), ainsi que l’endroit où afficher les fichiers HTML (popups, pages de nouvel onglet, etc.). En somme, il constitue la « feuille de route » qui définit la structure et le fonctionnement de l’extension.
- Service Worker : Le script Service Worker s’exécute en arrière-plan, indépendamment des pages web, et dispose d’un accès étendu aux API des extensions Chrome. Il permet à l’extension de gérer des paramètres du navigateur, traiter des requêtes réseau, communiquer avec d’autres composants de l’extension, et réaliser des actions sensibles comme intercepter le trafic, capturer des captures d’écran ou accéder à l’ensemble des cookies.
- Content Scripts : ce sont des fichiers JavaScript injectés dans certaines pages web, comme défini dans le manifest.json. Exécutés dans le contexte de la page, ils peuvent interagir directement avec le Document Object Model (DOM), ce qui leur permet de lire, modifier et manipuler le contenu de la page. Ils servent par exemple à changer l’apparence des pages, injecter des formulaires (y compris malveillants) ou encore extraire des données, telles que des identifiants stockés en local ou en session.
Fichiers HTML (popups, nouvelles pages, etc.) : une extension peut inclure des fichiers HTML standards afin de proposer des interfaces utilisateur. On les retrouve notamment pour :
-
Les popups : petites fenêtres qui s’ouvrent lorsque l’utilisateur clique sur l’icône de l’extension dans la barre d’outils du navigateur (définies par la directive default_popup dans le manifest.json).
-
Les nouveaux onglets : pages personnalisées qui remplacent la page par défaut affichée lors de l’ouverture d’un nouvel onglet.
-
Page d’options : interfaces dédiées à la configuration des paramètres de l’extension.
Les extensions de navigateur fonctionnent dans l’environnement Chrome et bénéficient d’un accès direct à ses API. Elles peuvent ainsi interagir avec les données traitées par le navigateur, y compris celles normalement protégées par l’App-Bound Encryption au niveau du système d’exploitation, puisque c’est le navigateur lui-même qui effectue le déchiffrement nécessaire à son fonctionnement. Ainsi, une extension chargée peut accéder et manipuler des données sensibles : identifiants, trafic réseau, redirections, et même contenu affiché à l’écran.
Installation d'extension Chrome
Les extensions sont généralement distribuées sous un format particulier, avec une extension de fichier .crx. Ce dernier, est une archive compressée regroupant tous les fichiers de l’extension (manifest, scripts, icônes, etc.), signée numériquement pour garantir son intégrité et son origine.
En général, les extensions Chromium s’installent selon quelques méthodes principales :
- Chrome Web Store : La méthode d’installation la plus courante passe par la boutique officielle Chrome Web Store. Dans ce cas, le navigateur télécharge automatiquement le fichier .crx correspondant, vérifie sa signature numérique et s’assure qu’il provient d’une source fiable. Les extensions distribuées via le store sont également soumises à un processus de validation par Google avant d’être mises à disposition des utilisateurs.
-
Extensions non empaquetées ou auto-signées : Lors du développement ou des phases de test, on peut charger une extension directement à partir d’un dossier local, sans passer par le Chrome Web Store. Pour cela, il suffit d’activer le « mode développeur » dans la page de gestion des extensions du navigateur, puis de choisir l’option « Load unpacked » et de pointer vers le dossier source de l’extension. Il est aussi possible d’installer une extension en glissant-déposant un fichier .crx dans la fenêtre du navigateur. Toutefois, si ce package est auto-signé et non issu du store officiel, Chrome affichera des avertissements, voire bloquera l’installation selon les règles de sécurité définies.

- Ligne de commande : Ligne de commande : Il est possible de charger des extensions au démarrage du navigateur en spécifiant leur répertoire via l’option --load-extension. Depuis la version 137 de Chromium, ce paramètre est désactivé par défaut. Pour réactiver cette fonctionnalité et charger une extension en ligne de commande, il est nécessaire d’ajouter le paramètre --disable-features=DisableLoadExtensionCommandLineSwitch.
Du point de vue d’un attaquant, tirer profit du Chrome Web Store est complexe en raison du processus de validation et d’approbation de Google. Même si des techniques comme l’obfuscation ou l’utilisation de WebAssembly peuvent parfois passer à travers les mailles du filet, le store reste une barrière bien plus importante que d’autres méthodes de déploiement, notamment l’installation locale. La méthode en ligne de commande, bien que fonctionnelle, est une technique largement connue. Sa visibilité ainsi que sa désactivation par défaut dans les dernières versions de Chromium la rendent peu adaptée. De plus, cette méthode est souvent exploitée par des acteurs malveillants, comme certains infostealers du type Chromeloader, ce qui la rend facilement détectable.
Nos recherches se focalisent donc sur la compréhension des mécanismes sous-jacents du chargement des extensions en mode développeur via la fonction « Charger l’extension non empaquetée ». Nous cherchons une voie moins documentée, capable de contourner ces contraintes habituelles pour offrir une méthode plus discrète de chargement d’extensions.
Mécanisme de chargement des extensions Chromium
Lors de l’installation, les extensions pour le navigateur Chromium sont enregistrées dans des fichiers spécifiques de préférences utilisateur sur les systèmes Windows. Ces fichiers, situés dans le répertoire AppData de l’utilisateur, servent de référentiels de configuration qui répertorient les extensions installées ainsi que leurs paramètres associés :
%USERNAME%/AppData/Local/Google/User Data/Default/Secure preferences
%USERNAME%/AppData/Local/Google/User Data/Default/Preferences
Le choix entre ces fichiers dépend de l’intégration de la machine : en dehors d’un domaine, Chromium utilise le fichier Secure Preferences local, tandis qu’en environnement géré via Active Directory ou la console Google Admin, la configuration passe par le fichier Preferences, permettant un contrôle centralisé des extensions.
Ci-dessous la structure d’un fichier de préférences Chrome typique, présentant ses sections principales et leur contenu :
{
"extensions":
{
"settings":
{
"<extension_hash>":{
"name" : "Extension name",
[...rest of manifest.json]
},
{...}
},
"ui": {
"developer_mode": true
}
}
[...]
"protection":{
"macs":{
"extensions":{
"settings":{
"<extension_hash>" : "<MAC>"
}
},
"extensions": {
"ui": {
"developer_mode": "<MAC>"
}
},
}
}
}
Le fichier Secure Preferences, utilisé sur les postes non intégrés à un domaine, présente une structure globalement similaire à celle du fichier Preferences standard. Cependant, il inclut en plus une propriété JSON supplémentaire appelée super_mac située à la racine du fichier.
Modifier un de ces fichiers implique de relever trois défis majeurs :
-
Pré-calculer l'id (hash) d'une extension
-
Calculer le MAC pour protection.macs.extensions.settings.[identifiant_extension]
-
Calculer le MAC pour le mode développeur (une nouvelle mesure de sécurité introduite dans les récentes versions de Chromium)
Génération du hash d’extension
Lorsqu’une extension est installée dans un navigateur basé sur Chromium, elle se voit attribuer un identifiant unique. Cet ID est généré en calculant d’abord le hash SHA-256 du bloc SubjectPublicKeyInfo encodé au format DER du certificat X.509 de la clé RSA publique de l’extension, si cette dernière est empaquetée. Si l’extension est non empaquetée ou en mode développement et ne possède pas de clé publique, le navigateur utilise à la place le chemin absolu du répertoire d’installation de l’extension comme entrée pour le calcul du hash. Dans les deux cas, les 32 premiers caractères du hash hexadécimal obtenu sont convertis, à l’aide d’un alphabet personnalisé (de a à p), pour produire l’identifiant final de l’extension.
Le code ci-dessous, extrait des sources de Chromium, est responsable de la génération de l’ID pour les extensions non empaquetées. Pour les extensions empaquetées, la clé publique est utilisée comme entrée à la place du chemin d’accès, mais le reste du processus (hachage et conversion) est réalisé par des fonctions utilitaires similaires.
// chromium/src/chrome/browser/extensions/unpacked_installer.cc:224
int UnpackedInstaller::GetFlags() {
std::string id = crx_file::id_util::GenerateIdForPath(extension_path_);
bool allow_file_access =
Manifest::ShouldAlwaysAllowFileAccess(Manifest::UNPACKED);
ExtensionPrefs* prefs = ExtensionPrefs::Get(service_weak_->profile());
if (allow_file_access_.has_value()) {
allow_file_access = *allow_file_access_;
} else if (prefs->HasAllowFileAccessSetting(id)) {
allow_file_access = prefs->AllowFileAccess(id);
}
int result = Extension::FOLLOW_SYMLINKS_ANYWHERE;
if (allow_file_access)
result |= Extension::ALLOW_FILE_ACCESS;
if (require_modern_manifest_version_)
result |= Extension::REQUIRE_MODERN_MANIFEST_VERSION;
return result;
}
// chromium/src/components/crx_file/id_util.cc:59
std::string GenerateIdForPath(const base::FilePath& path) {
base::FilePath new_path = MaybeNormalizePath(path);
std::string path_bytes =
std::string(reinterpret_cast<const char*>(new_path.value().data()),
new_path.value().size() * sizeof(base::FilePath::CharType));
return GenerateId(path_bytes);
}
std::string GenerateId(const std::string& input) {
uint8 hash[kIdSize];
crypto::SHA256HashString(input, hash, sizeof(hash));
std::string output = base::StringToLowerASCII(base::HexEncode(hash, sizeof(hash)));
ConvertHexadecimalToIDAlphabet(&output);
return output;
}
Cet ID d’extension sert de clé dans le système interne de gestion des extensions du navigateur (par exemple dans l’objet extensions.settings), où la valeur associée contient le manifeste de l’extension. Ce manifeste comprend des informations telles que le nom de l’extension, les permissions déclarées, le chemin d’installation et d’autres paramètres de configuration comme expliqué précédemment. Pour garantir un identifiant d’extension cohérent sur différents systèmes cibles, il est possible d’utiliser l’attribut key dans le fichier manifest.json de l’extension. Cela permet de pré-calculer et de contrôler l’identifiant unique de l’extension.
Le script Python ci-dessous illustre comment générer un ID d’extension ainsi que les clés publique et privée associées :
import base64 import hashlib from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa
def generate_extension_keys() -> tuple[str, str, str]: private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048 ) public_key = private_key.public_key() pub_key_bytes = public_key.public_bytes( encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo ) sha256_hash = hashlib.sha256(pub_key_bytes).digest() crx_id = translate_crx_id(sha256_hash[:16].hex()) pub_key = base64.b64encode(pub_key_bytes).decode('utf-8') priv_key_bytes = private_key.private_bytes( encoding=serialization.Encoding.DER, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption() ) priv_key = base64.b64encode(priv_key_bytes).decode('utf-8') return crx_id, pub_key, priv_key def translate_crx_id(input_str: str) -> str: translation = { '0': 'a', '1': 'b', '2': 'c', '3': 'd', '4': 'e', '5': 'f', '6': 'g', '7': 'h', '8': 'i', '9': 'j', 'a': 'k', 'b': 'l', 'c': 'm', 'd': 'n', 'e': 'o', 'f': 'p', } return ''.join(translation.get(c, c) for c in input_str) print(generate_extension_keys())
Le script génère un ID d’extension Chrome déterministe ainsi que la clé publique correspondante encodée en base64. Cette clé doit être ajoutée à la propriété key dans le fichier manifest.json de l’extension :
{ "manifest_version": 3, "name": "Synacktiv extension", "version": "1.0",
crx
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2lMCg6..." [...], }
Calcul du MAC d’extension : contournement du contrôle d’intégrité
Pour qu’une entrée d’extension dans le fichier Preferences soit considérée comme valide et chargée par Chromium, son MAC associé doit être calculé correctement. Ce MAC joue le rôle d’un contrôle d’intégrité, empêchant la modification arbitraire du fichier de préférences par des processus externes, comme expliqué préalablement. Concernant le calcul du MAC, une étude de 2020 menée par Pablo Picazo-Sanchez, Gerardo Schneider et Andrei Sabelfeld, intitulée "HMAC and ‘Secure Preferences’,"a fourni des éclairages précieux sur la partie calcul du HMAC. L’étude indique que la graine utilisée par Chrome pour le calcul du HMAC est codée en dur dans le fichier binaire resources.pak, généralement situé dans C:\Program Files\Google\Chrome\Application\resources.pak
.
Remarquablement, bien que cette recherche ait été réalisée sur une ancienne version de Chromium, le mécanisme décrit s’avère toujours valable, y compris pour la version 139 de Chromium au moment où ces lignes sont écrites (https://github.com/Pica4x6/SecurePreferencesFile/blob/main/Seed.py#L60).
Pour identifier plus précisément quel fichier contient la valeur de la graine, l’outil pak_util
de GRIT (Google Resource and Internationalization Tools) a été utilisé. Une analyse différentielle a été effectuée pour localiser précisément, dans le fichier resources.pak, la valeur de la graine. En extrayant et en comparant le contenu d’un resources.pak original avec une version légèrement modifiée au niveau de la clé, il a été établi que la graine se trouve dans le fichier numéro 146.
$ python3 pak_util.py extract resources.pak -o resources_v139/
$ python3 pak_util.py extract resources.pak -o resources_v139_dirty/
$ diff -bry resources_v139 resources_v139_dirty
Binary files resources_v139/146 and resources_v139_dirty/146 differ
$ xxd -p resources_v139/146
e748f336d85ea5f9dcdf25d8f347a65b4cdf667600f02df6724a2af18a212d26b788a25086910cf3a90313696871f3dc05823730c91df8ba5c4fd9c884b505a8
Le MAC est calculé en combinant cette graine statique, l’identifiant crx_id de l’extension et le contenu JSON des paramètres de l’extension dans le fichier de préférences. Ce calcul peut être conceptualisé ainsi :
# Pseudo-code for MAC calculation
# seed + "extensions.settings.<crx_id>" + {extension_settings...}
ext_mac = hmac.new(bytes.fromhex("e748f[...]4b505a8"),
("extensions.settings.<crx_id>" + json.dumps({extension_settings...})).encode('utf-8'),
hashlib.sha256).hexdigest().upper()
Il est à noter que, pour d’autres navigateurs basés sur Chromium tels que Microsoft Edge et Brave, la valeur de la clé a été observée comme étant nulle. Cette constatation est conforme aux observations de l’étude originale et reste valable cinq ans après sa publication.
Renforcement de la sécurité du mode développeur dans Chromium
À partir de la version 134 de Chromium, la gestion de l’état du bouton « Mode développeur » dans l’interface utilisateur a été renforcée. Son statut est désormais précisément contrôlé dans le fichier Preferences ou Secure Preferences, via l’entrée extensions.developer_mode. Il est important de noter que si ce mode n’est pas activé ici, les extensions peuvent être enregistrées mais ne seront jamais chargées ni actives. Cette valeur booléenne contrôlant le mode développeur n’est pas seulement stockée, elle doit aussi être signée avec un code d’authentification de message (MAC), tout comme l’enregistrement des extensions elles-mêmes.
Nos recherches ont révélé une dépendance critique : la clé statique utilisée pour signer correctement la valeur de la propriété developer_mode, générant ainsi son MAC, est exactement la même que celle qui sous-tend l’intégrité globale du système des extensions.
Contournement des politiques de sécurité
Bien que la technique précédemment décrite permette un chargement silencieux des extensions, les environnements d’entreprise mettent souvent en œuvre des politiques de sécurité pour restreindre le comportement du navigateur. Un contrôle courant est l’utilisation des politiques Chrome généralement appliquées via des Objets de Stratégie de Groupe (GPO) dans les domaines Windows, pour gérer l’installation et l’exécution des extensions. Ces politiques peuvent inclure des listes blanches ou noires d’extensions, bloquer totalement des extensions, ainsi que désactiver le mode développeur. Les organisations déploient généralement les modèles d’administration Chrome afin de configurer ces politiques. Par exemple, les politiques ExtensionInstallAllowlist et ExtensionInstallBlocklist sont fréquemment utilisées pour définir quelles extensions sont autorisées ou interdites, en se basant sur l'id d'une extension.
Technique 1 : Usurpation de hash d'extension autorisée (whitelist spoofing)
Sachant que les GPO se basent généralement sur le hash de l’extension pour la mise en liste blanche, nous avons exploré la possibilité d’usurper l’ID d’une extension légitime autorisée.
Le concept repose sur un scénario où un hash d’extension spécifique, par exemple celui d’un plugin approuvé par l’entreprise comme Adobe Acrobat Reader pour Chrome, est explicitement mis en liste blanche par la politique bien qu’il ne soit pas installé. Comme l’identifiant d’extension Chromium est dérivé de manière déterministe à partir de la clé publique RSA encodée en base 64 définie dans le manifeste, un attaquant pourrait exploiter cette clé pour reproduire le même identifiant d’extension Chrome et déployer une version modifiée sous forme d’extension non empaquetée.
Voici une structure claire en 5 étapes pour le processus d'usurpation d'ID d'extension Chromium :
- Installer une extension légitime et autorisée (par exemple, Adobe Acrobat PDF) depuis le Chrome Web Store.
- Récupérer l’ID de l’extension à partir de l’URL ou des détails de la page des extensions du navigateur.
- Extraire l’attribut clé publique de l’extension en inspectant la console du service worker (via
chrome.runtime.getManifest().key
) ou en téléchargeant et en analysant le paquet.crx
depuis les serveurs de mise à jour de Google. - Mettre à jour le fichier
manifest.json
de votre extension en définissant l’attribut key avec la clé publique extraite, ce qui permet d’usurper l’ID de l’extension. - Injecter l’extension modifiée dans les préférences du navigateur et signer le MAC pour finaliser l’installation.
Technique 2 : Écrasement d’extension (Extension Stomping)
Nous avons observé un comportement intéressant lorsque qu’une extension non empaquetée était configurée pour usurper l’identifiant d’une extension déjà installée. Dans ce cas, Chromium privilégiait la version non empaquetée, qui venait remplacer l’extension légitime du Chrome Web Store sur la page chrome://extensions.
Ce comportement, confirmé à la fois sur Chrome et Edge (par exemple avec Adobe PDF), montre que lorsque des identifiants d’extension entrent en collision, le navigateur privilégie les extensions non empaquetées chargées localement, offrant ainsi un moyen furtif de remplacer celles considérées comme fiables.
Technique 3 : Neutralisation des GPO via HKCU
La méthode la plus efficace identifiée pour contourner les restrictions d’extensions imposées par les GPO exploite l’ordre de traitement des stratégies de groupe Windows.
Les politiques sont appliquées selon une séquence spécifique connue sous le nom de LSDOU :
- Local (Local Group Policy on the machine itself)
- Site (Active Directory Sites)
- Domain (Active Directory Domains)
- Organizational Unit (Active Directory OUs)
Les politiques Chromium appliquées via GPO sont stockées sous la clé de registre HKCU\Software\Policies*, ce qui correspond à la ruche HKEY_CURRENT_USER. Bien que cette localisation soit dans HKCU, elle est protégée contre les modifications par les utilisateurs standards.
Cependant, un attaquant disposant de privilèges administratifs peut modifier, ajouter ou supprimer des entrées dans les clés HKCU\Software\Policies\Google\Chrome\ExtensionInstallAllowlist ou ExtensionInstallBlocklist, ce qui lui permet de contourner les restrictions d’extensions et de compromettre l’application des politiques Chrome.
PS> reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallAllowlist" /f
PS> reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallBlocklist" /f
Démonstration
L’exécution manuelle de ces étapes, depuis la dérivation du hash de l’identifiant d’extension à partir de la clé publique jusqu’à la modification du manifeste, le calcul du MAC, et la mise à jour des fichiers de préférences, est à la fois complexe et sujette aux erreurs. Pour simplifier ce processus, un script sera publié sur le dépôt GitHub de Synacktiv.
Ci-dessous, une démonstration utilisant notre outil met en lumière la compromission du navigateur via les extensions, incluant un déploiement distant via SMB ainsi qu’un serveur de commande et contrôle (C2) personnalisé.
Conclusion
Cette recherche a révélé une technique efficace, peu exploitée, permettant de charger arbitrairement des extensions dans les navigateurs basés sur Chromium au sein d’environnements de domaine Windows. En manipulant les fichiers de préférences internes de Chromium, nous avons démontré comment injecter et activer des extensions de manière programmatique, contournant ainsi les méthodes d’installation standard.
- Pour les équipes Red Team, cette technique offre une voie discrète et persistante pour compromettre le navigateur et exfiltrer des données. Le déploiement est polyvalent, supportant le chargement distant via SMB, l’intégration avec des implants au niveau système, ou l’utilisation de projets comme CursedChrome pour transformer le navigateur en proxy HTTP. Le développement d’agents personnalisés et de frameworks C2 permet l’exécution à distance de JavaScript directement dans le processus natif de Chromium, contournant des mécanismes de sécurité tels que le chiffrement lié à l’application (app-bound encryption).
-
Pour les équipes Blue Team, une compréhension approfondie de ces techniques est essentielle afin d’améliorer les capacités de détection. Cela souligne la nécessité cruciale de surveiller les modifications non autorisées des fichiers de préférences du navigateur (notamment celles effectuées par des processus hors navigateur), les enregistrements inhabituels d’extensions, ainsi que les modifications suspectes des clés de registre HKCU ou HKLM liées aux politiques logicielles.
Le navigateur, en tant qu’interface principale d’accès à des données sensibles dans le cloud, reste une surface d’attaque critique. Bien que ces connaissances visent à renforcer à la fois les postures offensives et défensives, elles mettent aussi en lumière la difficulté intrinsèque à protéger cryptographiquement les secrets internes du navigateur, tels que la clé permettant de signer les fichiers de préférences. En effet, toute solution réellement robuste devrait prendre en compte les mécanismes de sécurité spécifiques à chaque système d’exploitation (comme DPAPI sur Windows), sans compromettre la compatibilité multiplateforme.