Chaque extension Chrome est fournie avec un fichier manifest.json, qui définit une grande partie de ce qu’elle peut faire côté navigateur : API demandées, motifs d’hôtes, scripts de contenu statiques, autorisations facultatives et connexions externes autorisées. Ce fichier est public dans le package que tu installes. En revanche, il ne prouve pas quelles capacités déclarées sont réellement utilisées par le code à l’exécution, quelles données quittent la machine, ni quels accès à des comptes passent par une connexion web distincte.
J’ai passé en revue les dix extensions de scraping et d’automatisation du navigateur retenues pour cet audit, y compris celle de Thunderbit, qui est la nôtre. L’éventail est très large. L’une ne déclare aucun accès permanent aux sites. Une autre en déclare treize, dont clipboardRead. Thunderbit est la seule extension de cet ensemble à déclarer debugger, une capacité d’attachement CDP large, avec un profil de risque différent de l’accès aux pages, d’OAuth ou de scripts fournis par l’utilisateur.
Rien de tout cela n’est une accusation. Une autorisation large est souvent la seule manière honnête de construire une fonctionnalité donnée, et une autorisation étroite peut simplement vouloir dire que le produit en fait moins. Le point important, c’est que l’écart est immense, qu’il est publié, et qu’il n’apparaît jamais dans un tableau comparatif.
Méthode
Chaque extension a été téléchargée en .crx depuis le propre point de mise à jour de Google — la même URL que Chrome utilise lui-même — puis décompressée et analysée. Aucune extension n’a été installée et aucun code d’extension n’a été exécuté. Il s’agit d’une lecture d’un fichier JSON.
Les téléchargements ont été espacés d’environ une requête toutes les deux secondes. Chaque .crx, son SHA-256 et le manifest.json extrait sont conservés comme artefacts. Thunderbit est passé par le même script que les neuf autres, sans traitement particulier, donc sa ligne est dérivée exactement de la même façon.
L’analyse s’appuie sur deux catégories de preuves et les garde séparées :
- Comportement statique déclaré : motifs d’hôtes et entrées
content_scripts, y comprismatches,run_atetall_frames. - Capacité disponible pour le code à l’exécution : API nommées dans
permissionsouoptional_permissions. Ces déclarations indiquent ce que le code pourrait demander ou invoquer, pas ce qu’il fait effectivement.
Aucun score ordinal du type « le plus puissant » n’est attribué. debugger, userScripts, l’accès large aux hôtes, les scopes OAuth, l’accès au presse-papiers et la messagerie externe exposent des données différentes et nécessitent des conditions préalables différentes. Les comparer exige un modèle de menace que cet audit basé sur le seul manifeste ne fournit pas.
Les tailles ci-dessous sont des totaux décompressés en MiB (2²⁰ octets), additionnés à partir des entrées ZIP.
À la date du 2026-07-29. Les extensions se mettent à jour ; vérifie à nouveau avant de citer.
Ce que déclarent dix manifests

Référence officielle : guide Chrome sur la déclaration des permissions.
| Extension | Version | Décompressé | Fichiers | Permissions | Accès aux sites | Accède à file:// |
|---|---|---|---|---|---|---|
| Axiom.ai | 5.1.0 | 37.1 MiB | 232 | 8 | http://*/* + https://*/* | ✅ |
| Table Capture | 11.0.41 | 21.1 MiB | 115 | 4 (+3 facultatives) | <all_urls> | ✅ |
| Magical | 3.119.1 | 16.8 MiB | 395 | 13 (+2 facultatives) | <all_urls> | ✅ |
| Thunderbit (la nôtre) | 4.6.4 | 15.9 MiB | 78 | 8 reconnues (+1 chaîne de tableau non reconnue : commands) | <all_urls> | ✅ |
| Clay for Chrome | 1.0.0 | 6.3 MiB | 51 | 6 | *://*/* (n’injecte que sur son propre domaine) | — |
| Listly | 0.9.6 | 3.5 MiB | 84 | 7 | http://*/*, https://*/*, file:///*.html | ✅ |
| Hexomatic | 1.8.4 | 2.7 MiB | 37 | 2 | domaines propres uniquement | — |
| Agenty | 2.9.7 | 2.2 MiB | 49 | 4 | aucun déclaré | — |
| Clip to Clay | 1.8.0 | 0.7 MiB | 16 | 4 | 2 domaines nommés | — |
| TexAu v2 | 1.6.6 | 0.3 MiB | 12 | 6 | 14 domaines nommés | — |
Deux autres figuraient sur la liste initiale et ne sont pas dans le tableau, pour des raisons qui méritent d’être signalées à part.
L’écart relève du choix de conception, pas de la taille
Agenty ne déclare aucune autorisation d’hôte et ne fournit aucun script de contenu. Ses quatre permissions sont activeTab, scripting, identity et identity.email. activeTab est la plus restrictive : elle donne accès à l’onglet courant uniquement après un clic sur l’extension, et seulement jusqu’à ce que tu changes de page. Rien ne s’exécute sur tes pages tant que tu ne l’as pas déclenché. Pour 2.2 MiB.
Axiom.ai déclare http://*/* et https://*/*, injecte des scripts de contenu correspondant à <all_urls> et se décompresse à 37.1 MiB sur 232 fichiers — dix-sept fois la taille d’Agenty, avec un accès permanent à chaque page que tu visites.
Hexomatic est du côté d’Agenty : deux permissions (storage, tabs), aucune autorisation d’hôte, scripts de contenu limités à ses deux domaines propres.
Clay for Chrome présente un troisième profil qu’il faut distinguer : il déclare *://*/* comme autorisation d’hôte, mais n’injecte des scripts de contenu que sur son propre domaine. La capacité permanente est large ; le comportement automatique est étroit. Un tableau de permissions seul mélange les deux.
Cinq des dix peuvent atteindre des fichiers sur ton disque
file:/// n’est pas un site web. C’est ton système de fichiers local affiché dans un onglet du navigateur — un PDF que tu as ouvert, un export HTML, une facture téléchargée.
Référence officielle : documentation Chrome sur les motifs de correspondance.
Trois extensions le disent explicitement. Deux y parviennent sans le nommer : <all_urls> inclut le schéma file:.
| Extension | Comment elle atteint file:// | Le mentionne-t-elle dans son manifest ? | Où |
|---|---|---|---|
| Magical | correspond à file:///* — tout fichier local rendu par Chrome, pas seulement les HTML — dans quatre de ses six entrées de scripts de contenu | ✅ | scripts de contenu et web_accessible_resources |
| Listly | correspond à file:///*.html | ✅ | scripts de contenu |
| Table Capture | scripts de contenu <all_urls>, et il nomme aussi le schéma | ✅ | web_accessible_resources |
| Axiom.ai | simplement grâce au joker <all_urls> | — | nulle part |
| Thunderbit (la nôtre) | simplement grâce au joker <all_urls> | — | nulle part |
http://*/* et https://*/* ne couvrent pas file:// ; <all_urls> et *://*/* diffèrent aussi sur ce point. Les cinq ici sont celles dont les déclarations atteignent le schéma d’une manière ou d’une autre — pas en raison du type de joker choisi.
Chrome encadre tout cela derrière un interrupteur par extension « Autoriser l’accès aux URL de fichiers », désactivé par défaut ; la déclaration est donc une demande, pas une autorisation effective. Cinq sur dix est le comptage honnête, et deux de ces cinq n’écrivent jamais file:// dans leur manifest : Axiom.ai et la nôtre.
Ce comptage inclut web_accessible_resources, pas seulement les scripts de contenu et les autorisations d’hôte. Table Capture y mentionne file://*/* ; omettre ce bloc placerait à tort cette extension parmi celles dont les manifests atteignent des fichiers sans nommer le schéma.
Des permissions invisibles tant qu’elles ne sont pas demandées

optional_permissions sont déclarées à l’avance mais demandées à l’exécution ; elles n’apparaissent donc pas dans la fenêtre d’installation. Deux extensions les utilisent, et l’une est importante.
| Extension | optional_permissions | Celle qui compte |
|---|---|---|
| Table Capture | userScripts, downloads, identity | userScripts peut exécuter des scripts fournis par l’utilisateur dans le contexte des pages après activation du garde-fou Chrome |
| Magical | downloads, webRequest | webRequest observe le trafic réseau |
userScripts n’est pas visible tant qu’elle n’est pas demandée, et échappe à quiconque ne lit qu’un simple total de permissions.
Elle est aussi soumise à un garde-fou que les autres permissions de cet audit n’ont pas, et l’ignorer la surestimerait. Déclarer userScripts ne suffit pas pour l’utiliser : Chrome exige d’abord une action explicite de l’utilisateur. Avant Chrome 138, il s’agissait du Mode développeur, activé globalement via chrome://extensions. Depuis Chrome 138, c’est un interrupteur Autoriser les scripts utilisateur propre à chaque extension, sur sa page de détails, désactivé par défaut. Pour une installation normale, la capacité est donc déclarée mais inactive. La formulation exacte est conditionnelle : Table Capture peut rendre l’API userScripts disponible après que l’utilisateur a activé le garde-fou de Chrome. Cet audit n’a pas mesuré la fréquence à laquelle les utilisateurs visitent cette page de réglages ou activent l’option.
Ni l’un ni l’autre n’est caché ; les deux figurent dans le manifest. Un tableau qui ignore le bloc facultatif sous-estime deux produits.
Le moment de l’injection, pas seulement le périmètre
La manière dont un script de contenu est injecté est souvent ignorée, alors qu’elle change la lecture. document_start est le déclencheur le plus tôt que Chrome propose ; all_frames atteint les intégrations tierces.
Tout ce qui, dans ce lot, injecte statiquement dans tous les cadres, classé par moment déclaré :
| Extension | run_at | all_frames | Motif de correspondance du script de contenu |
|---|---|---|---|
| Table Capture | document_start | ✅ | <all_urls> |
| Listly | document_start | ✅ | file:///*.html plus tout http et https |
| Axiom.ai | document_start | ✅ | domaines propres uniquement |
| Clay for Chrome | document_start | ✅ | domaines propres uniquement |
| Thunderbit (la nôtre) | document_end | ✅ | <all_urls> |
| Magical | document_idle | ✅ | file:///* plus un large éventail http et https |
| TexAu | document_idle (non défini) | ✅ | quatorze motifs nommés |
Table Capture et Listly utilisent le déclencheur le plus précoce sur des motifs de correspondance larges. Axiom.ai et Clay for Chrome emploient le même timing sur leurs propres domaines uniquement — même agressivité, cible plus étroite.
Pour les déclarations statiques, <all_urls> plus all_frames constitue le plafond de largeur de correspondance, et Table Capture comme Thunderbit s’y situent. Leur timing déclaré diffère : Table Capture utilise document_start ; le script de contenu statique de Thunderbit utilise document_end. Les API d’exécution constituent une autre catégorie de capacité et ne peuvent pas être inférées à partir de ce tableau.
Un simple comptage des permissions est un mauvais résumé statistique. Table Capture ne déclare que quatre permissions — moins que la plupart ici — et injecte à document_start dans tous les cadres sur <all_urls>, plus userScripts sur demande.
Qui est autorisé à envoyer des messages à l’extension
externally_connectable contrôle quelles pages web ou quelles autres extensions peuvent envoyer directement des messages au script d’arrière-plan d’une extension. Son comportement par défaut est contre-intuitif.
Omettre la clé est l’option la plus permissive. Par défaut, lorsqu’externally_connectable est absent, Chrome considère que toute extension peut se connecter, tandis qu’aucune page web ne le peut. Le déclarer sert à restreindre.
À cette lumière, le tableau s’inverse :
| Extension | Déclaration externally_connectable | Qui peut lui envoyer des messages |
|---|---|---|
| Agenty | omise | Par défaut permissif — toute extension peut se connecter, aucune page web ne peut |
| Clay for Chrome | omise | Par défaut permissif — toute extension peut se connecter, aucune page web ne peut |
| Clip to Clay | omise | Par défaut permissif — toute extension peut se connecter, aucune page web ne peut |
| Listly | omise | Par défaut permissif — toute extension peut se connecter, aucune page web ne peut |
| Table Capture | omise | Par défaut permissif — toute extension peut se connecter, aucune page web ne peut |
| TexAu | omise | Par défaut permissif — toute extension peut se connecter, aucune page web ne peut |
| Thunderbit (la nôtre) | omise | Par défaut permissif — toute extension peut se connecter, aucune page web ne peut |
| Hexomatic | huit ID d’extension et six origines web | Ouvre les deux canaux à partir d’un point de départ fermé |
| Axiom.ai | sept origines web, pas de ids | Canal extension fermé, sept pages web ouvertes |
| Magical | {"ids": [], "matches": []} | La seule extension ici à fermer explicitement les deux canaux |
La règle de Chrome a deux niveaux. D’après la référence du manifeste :
| Situation | Qui peut se connecter |
|---|---|
| la clé entière est absente | « toutes les extensions peuvent se connecter, mais aucune page web ne peut » |
clé présente, ids non défini ou [] | « aucune extension ni application ne peut se connecter » |
clé présente, matches non défini ou [] | « aucune page web ne peut se connecter » |
Le comportement permissif s’attache donc à l’absence de la clé entière. Une fois la clé présente, les deux sous-champs partent fermés, et le fait de leur donner des valeurs élargit chaque canal.
Axiom.ai déclare la clé avec seulement matches. Son ids est donc non défini, ce qui signifie que aucune extension ne peut lui envoyer de message — le canal extension est fermé, pas laissé ouvert. Ce qu’il a ouvert, ce sont sept origines web, dont une seule est un domaine Axiom : deux sont des tiers non attribuables (*://*.tgwc.space/*, *://*.bitmachine.co.uk/*) et les autres sont localhost, 0.0.0.0, un hôte Google APIs et une grande plateforme sociale qu’il n’exploite pas.
Hexomatic ouvre son canal extension à huit ID nommés. Avec la clé présente, la base est zéro extension ; en nommer huit l’élargit à huit. Ses six matches élargissent l’autre canal depuis rien, et deux d’entre eux sont http://localhost:8000/* et http://localhost:3000/* en HTTP simple — tout service répondant sur ces ports sur la machine de l’utilisateur entre dans la liste d’autorisation.
Sept des dix omettent complètement la clé, y compris la nôtre, et ce sont elles qui restent au comportement permissif pour la messagerie extension-à-extension. Deux extensions ferment ce canal : Magical explicitement avec ids: [], et Axiom.ai en déclarant la clé sans jamais mentionner ids. Magical est la seule qui ferme les deux.
Cette dernière phrase explique pourquoi il faut lire les manifests plutôt que compter les permissions. Une extension peut être large sur un axe et la plus stricte du lot sur un autre.
L’axe que personne ne compte : les scopes OAuth
Un manifest peut contenir un bloc oauth2, et les scopes qu’il contient donnent accès à tes comptes chez d’autres entreprises — une forme de portée différente de tout ce qui précède, et qu’aucun total de permissions ne reflète.
Référence officielle : liste des scopes Google OAuth 2.0.
| Extension | Scopes oauth2 demandés |
|---|---|
| Axiom.ai | openid, email, profile, auth/drive, auth/spreadsheets |
| Table Capture | auth/spreadsheets, auth/userinfo.email |
| Agenty | openid, email, profile |
| Les sept autres, y compris la nôtre | aucun déclaré |
https://www.googleapis.com/auth/drive est le scope large. Google propose un scope plus étroit, drive.file, qui n’autorise l’accès qu’aux fichiers créés par l’application elle-même ou explicitement choisis par l’utilisateur ; auth/drive permet de voir, modifier, créer et supprimer sur l’ensemble du Drive de l’utilisateur. auth/spreadsheets a la même logique pour toute feuille de calcul accessible au compte.
Deux limites à ce que ce tableau prouve. Un scope est demandé, pas accordé — Google affiche un écran de consentement et l’utilisateur peut refuser, et l’extension peut ne jamais appeler l’API. Par ailleurs, le manifest ne voit que l’OAuth passé par le flux identity de Chrome ; une extension qui te renvoie vers une page de connexion web ne déclarerait rien ici. Les sept zéros signifient « non demandé dans ce fichier », pas « aucun accès à ton compte Google » — y compris pour la nôtre, ce qui explique pourquoi cet axe est présenté plutôt que revendiqué comme signe de faiblesse.
Notre extension, sur la même échelle
Thunderbit 4.6.4 est passé par le même analyseur de manifeste que les neuf autres. Le package fait 15.9 MiB décompressés sur 78 fichiers.
Comportement statique déclaré : <all_urls> apparaît dans les permissions d’hôte et dans les correspondances des scripts de contenu. Le script statique s’exécute dans all_frames à document_end. Comme <all_urls> inclut file:, le manifest peut atteindre les fichiers locaux une fois que l’utilisateur active l’option d’accès aux fichiers de Chrome. Thunderbit omet aussi externally_connectable, donc Chrome autorise par défaut les messages de toute extension, mais d’aucune page web.
Plafond de capacité à l’exécution : le tableau permissions contient neuf chaînes : activeTab, commands, debugger, offscreen, scripting, sidePanel, storage, tabGroups et tabs. Chrome en reconnaît huit comme permissions ; commands est une clé de manifeste de niveau supérieur et n’a aucun effet en tant qu’entrée de ce tableau. Thunderbit est la seule extension de l’ensemble à déclarer debugger, qui peut attacher CDP à un onglet. Le manifest rend aussi scripting disponible pour un enregistrement à l’exécution. Ces API créent des capacités qui vont au-delà de la ligne statique document_end, mais la lecture du manifest ne permet pas d’établir que Thunderbit invoque une méthode CDP particulière ni qu’il enregistre un script à un moment plus précoce.
Cette distinction écarte plusieurs comparaisons tentantes mais invalides. L’absence d’une permission cookies plus étroite ne borne pas ce qu’un code doté de debugger pourrait accéder. L’absence de clipboardRead ne prouve pas qu’un accès au presse-papiers est impossible. Inversement, la présence de debugger ne prouve pas que ces chemins sont utilisés. Répondre à l’une de ces questions exige une inspection du code source ou un traçage à l’exécution, aucun des deux n’ayant été réalisé.
Avec cet instrument, Thunderbit est large sur l’accès statique aux sites, unique dans ce lot pour déclarer debugger, et au comportement par défaut de Chrome pour la messagerie extension-à-extension. Il n’existe pas de classement unique du « plus puissant », car l’audit ne fournit aucun modèle de menace commun entre CDP, OAuth, userScripts, le presse-papiers et l’accès aux hôtes.
Le design retenu que personne ne met en avant
TexAu fait 0.3 MiB — le plus petit de ce groupe d’un facteur deux — et nomme quatorze sites précis plutôt que d’utiliser un joker : réseaux sociaux, plateforme de développeurs, plateformes de publication, produit de chat, fournisseur de données métier et son propre domaine. Ses scripts de contenu correspondent exactement à ces quatorze cibles.
On peut lire son manifest et savoir précisément où l’extension est active. C’est aussi une forme de transparence produit : la liste des cibles dit plus clairement à quoi sert l’outil que le marketing.
Le compromis est réel : une liste nommée ne peut pas scraper un site qui n’en fait pas partie, et chaque nouvelle cible nécessite une publication. Mais « quatorze domaines nommés » et « n’importe quelle URL existante » sont deux propositions très différentes, et une seule est lisible.
Deux produits qui n’étaient pas ce que la liste disait
L’extension de Captain Data n’est pas distribuée publiquement. Le point de mise à jour de Google renvoie HTTP 204 avec un corps vide pour son ID d’extension — la réponse attendue pour quelque chose que le store ne sert pas anonymement. En revanche, sa page de présentation a bien été servie anonymement — HTTP 200, 509 829 octets. Ce que la capture n’a pas pu y trouver, ce sont une chaîne de version, une date de dernière mise à jour ou un nombre d’installations ; les notes du script indiquent qu’un null à cet endroit est une preuve faible, et aucun mur de connexion n’a été observé. L’ID est réel et de première partie, donc la lecture la plus probable est une distribution par lien uniquement ou non listée, mais je n’ai pas pu distinguer cela d’un déréférencement et je ne vais pas spéculer.
Dataflow Kit n’a pas d’extension Chrome du tout. Son site décrit une application web hébergée, avec sélection au clic et API REST. Elle figurait pourtant sur une liste restreinte d’extensions Chrome — ce qui explique généralement comment ces listes sont constituées.
Obsolescence et portée, puisqu’on peut vérifier les deux gratuitement
Les métadonnées du Store ajoutent un contexte de sélection produit au-delà des permissions. Les mêmes champs ont été relevés pour chaque extension le 2026-07-30.
| Extension | Version du Store | Dernière mise à jour | Palier d’installations |
|---|---|---|---|
| Thunderbit (la nôtre) | 4.6.4 | 28 juillet 2026 | 200 000 |
| Listly | 0.9.6 | 25 juillet 2026 | 100 000 |
| Axiom.ai | 5.1.0 | 20 juillet 2026 | 100 000 |
| Table Capture | 11.0.41 | 26 juin 2026 | 200 000 |
| Magical | 3.119.1 | 4 avril 2026 | 200 000 |
| Agenty | 2.9.7 | 8 février 2026 | 10 000 |
| TexAu | 1.6.6 | 20 août 2025 | 7 000 |
| Clay for Chrome | 1.0.0 | 9 avril 2025 | 10 000 |
| Clip to Clay | 1.8.0 | 8 avril 2025 | 1 000 |
| Hexomatic | 1.8.4 | 6 septembre 2024 | 3 000 |
| Captain Data | — | — | non servi publiquement |
Trois produits n’ont pas été publiés depuis plus d’un an, et Hexomatic depuis près de deux ans. Pour les extensions, cela compte davantage que pour des bibliothèques : Chrome publie une version stable environ toutes les quatre semaines, et la plateforme d’extensions elle-même change en permanence en dessous. userScripts a déplacé son garde-fou utilisateur dans Chrome 138 ; une extension publiée pour la dernière fois en 2024 a été construite selon un ensemble de règles différent de celui que le navigateur applique maintenant.
Deux précisions utiles : les comptes d’installations sont arrondis par Google — 1 000 / 3 000 / 7 000 / 10 000 / 100 000 / 200 000 — et ne permettent donc que des comparaisons d’ordre de grandeur ; plusieurs produits affichent d’ailleurs des chiffres plus élevés dans leur propre marketing. Une date récente est un fait de publication, pas un verdict sur la qualité de maintenance ou le niveau de risque des permissions.
Un effet secondaire utile : la version du Store correspond à la version du manifest dans chacun des dix packages analysés. Les fichiers CRX que cet audit a lus sont bien ceux que le Store sert aujourd’hui, et non des copies obsolètes.
La fraîcheur change le niveau de suivi qu’une sélection mérite ; elle ne change pas la sémantique du manifest. Une extension à domaine nommé, mise à jour il y a un an, peut toujours exposer moins de surface qu’une extension à joker publiée hier. Le package plus récent peut malgré tout être le meilleur choix opérationnel s’il suit rapidement les évolutions de Chrome. Pour une présélection, utilise la date du Store pour décider quoi retester, puis le manifest pour déterminer ce qui mérite une analyse de capacité plus poussée. Ne transforme pas les deux colonnes en un score unique.
Ce qu’un manifest ne dit pas
Une permission déclarée est un plafond, pas un comportement. <all_urls> signifie qu’une extension peut lire chaque page. Cela ne veut pas dire qu’elle le fait, ni que des données quittent ta machine. Déterminer ce qui se passe réellement exige d’observer le trafic réseau à l’exécution — un travail différent, non réalisé ici, et rien de ce qui précède ne doit être lu comme une preuve d’abus.
Lecture connexe : expérience de testabilité des extensions Chrome.
Trois autres limites :
- Chrome encadre fortement tout cela. L’accès aux fichiers est désactivé par défaut ;
activeTabest volontairement étroit ; les permissions facultatives nécessitent une invite à l’exécution ; l’utilisateur voit la liste des permissions à l’installation. - Les permissions larges sont souvent nécessaires. Un outil dont le rôle est « extraire un tableau depuis n’importe quelle page » ne peut pas fonctionner avec une liste de domaines nommés. Une portée étroite est parfois de la discipline, parfois simplement un produit plus limité.
- Une version, un jour. Tous les chiffres proviennent du package servi le 2026-07-29.
Corrections matérielles apportées à l’analyse
Les comptages publiés reposent sur trois règles faciles à mal appliquer lorsqu’on écrit rapidement un analyseur de manifest. Premièrement, <all_urls> inclut le schéma file:, mais Chrome maintient l’accès réel aux fichiers derrière un interrupteur contrôlé par l’utilisateur. Deuxièmement, web_accessible_resources.matches doit être examiné en parallèle des scripts de contenu et des autorisations d’hôte ; c’est là que Table Capture nomme explicitement file://*/*. Troisièmement, externally_connectable a des valeurs par défaut différentes selon que la clé entière est absente ou qu’elle existe avec un sous-champ vide. Les tableaux ci-dessus appliquent ces règles de façon cohérente.
Le total des permissions de Thunderbit distingue aussi les chaînes brutes des permissions Chrome reconnues. Son tableau contient neuf entrées, mais commands appartient au niveau supérieur, donc le comptage effectif utilisé ici est de huit permissions reconnues plus une chaîne non reconnue. Enfin, les déclarations statiques content_scripts ne prouvent pas que le code appelle scripting.registerContentScripts ou une méthode CDP. Ces possibilités relèvent uniquement des capacités d’exécution, jamais d’un comportement observé. Les manifests bruts, les hachages CRX et la sortie de l’analyseur devraient être liés en annexe de publication afin que les lecteurs puissent vérifier ces normalisations sans faire confiance au texte.
Pour une vraie décision d’installation, compare au moins quatre dimensions séparément : quelles pages sont couvertes par défaut, quelle action explicite de l’utilisateur débloque plus d’accès, quelles API du navigateur ou des comptes deviennent disponibles, et quels appelants externes peuvent envoyer des messages à l’extension. Le modèle activeTab d’Agenty, les userScripts verrouillés de Table Capture, le scope Drive d’Axiom.ai et la déclaration debugger de Thunderbit ne sont pas des points sur une même échelle linéaire. Ce sont des réponses différentes à des questions de menace différentes.
Voici cette comparaison appliquée à quatre designs volontairement différents :
| Extension | Portée des pages visible dans le manifest | Garde-fou supplémentaire | Capacité hors page dans cet audit | Position vis-à-vis des appelants externes |
|---|---|---|---|---|
| Agenty | aucune autorisation d’hôte ni script de contenu statique | l’utilisateur active activeTab sur l’onglet courant | permissions Chrome Identity | clé omise : toute extension peut se connecter, aucune page web ne peut |
| Table Capture | scripts statiques sur <all_urls> dans tous les cadres à document_start | l’accès aux fichiers est désactivé par défaut ; userScripts nécessite le garde-fou utilisateur séparé de Chrome | userScripts, downloads et identity facultatives | clé omise : toute extension peut se connecter, aucune page web ne peut |
| Axiom.ai | accès joker HTTP et HTTPS ; scripts statiques à document_start sur ses propres domaines | consentement OAuth pour les scopes Google demandés | scopes OAuth Drive et Sheets déclarés | appelants extension fermés ; sept origines web ouvertes |
| Thunderbit | accès d’hôte <all_urls> et scripts statiques dans tous les cadres à document_end | l’accès aux fichiers est désactivé par défaut ; l’attachement à debugger a un comportement visible et contrôlé par Chrome | debugger, scripting, tabs et API de navigateur associées déclarées | clé omise : toute extension peut se connecter, aucune page web ne peut |
Ce tableau ne désigne toujours pas de gagnant. Le faible accès permanent aux pages d’Agenty ne dit rien de ce que son backend fait des données soumises. Les scopes de compte d’Axiom.ai ne se comparent pas à une extension lisant la page courante. La déclaration userScripts de Table Capture est inerte tant que l’utilisateur n’active pas son garde-fou séparé. La permission debugger de Thunderbit expose une large surface de contrôle du navigateur, mais le manifest ne révèle pas quels domaines ou méthodes CDP son code appelle. Chaque ligne te dit quoi inspecter ensuite : trafic réseau à l’exécution, code source, flux de consentement ou traces d’API navigateur.

La même séparation est importante quand on lit l’invite d’installation de Chrome. Un simple comptage des permissions ne peut pas montrer le timing, la portée par cadre, le scope OAuth, web_accessible_resources, ni la présence ou l’absence de la clé externally_connectable. Inversement, une déclaration large ne prouve pas une collecte ni une exfiltration. Le résultat utile d’un audit de manifest est un plan de test d’exécution priorisé : identifier la surface de données, noter le garde-fou utilisateur, puis observer si le chemin déclaré est réellement utilisé.
Comment lire le vôtre
Lecture connexe : guide de l’automatisation du navigateur.
chrome://extensions→ Détails affiche les accès aux sites accordés et permet de les passer à sur clic pour tout ce qui n’a pas besoin d’un accès permanent. Cela réduit la moitié « accès aux sites » de ce qui précède. Cela ne touche pas à la messagerie entrante (externally_connectableatteint le service worker quoi qu’il arrive) ni aux permissions au niveau du navigateur. La déclarationdebuggerde Thunderbit compte ici. La documentation sécurité des extensions de Chromium indique que l’API debugger « peut dans certains cas aussi contourner d’autres restrictions habituelles, comme les autorisations d’hôte ou l’accès aux fichiers », donc le réglage de l’accès aux sites sur « sur clic » ne borne pas ce qu’elle peut atteindre. Ce contrôle ne touche pas non plustabs,webNavigation,clipboardRead,downloadsni rien dansoptional_permissions.- Pour le fichier brut, le package se trouve dans le répertoire Chrome
Extensions/<id>/<version>/. Lis six champs :permissions,optional_permissions,host_permissions,content_scripts(lesmatches,run_atetall_framesqu’ils contiennent),externally_connectable— en gardant à l’esprit qu’une clé absente est permissive pour les appelants d’extension — etweb_accessible_resources, dont lesmatchespeuvent nommer des schémas que les scripts de contenu ne nomment jamais. Le dernier champ de Thunderbit comporte deux entrées<all_urls>exposantindex.htmlet deux scripts embarqués à toute origine, avecuse_dynamic_url: false, ce qui permet à une page de vérifier si ces URL d’extension stables résolvent. - Vérifie la date de dernière mise à jour de la fiche par rapport à la version actuelle de Chrome.
Divulgation et ressources : cet article est publié par Thunderbit, dont l’extension figure dans le même tableau et le même analyseur. Notre pilier open source des scrapeurs couvre les outils hors extension.
Essayer Thunderbit pour l’extraction de données web
Version courte
Dix extensions de scraping et d’automatisation, la nôtre comprise, ont été lues à partir de leurs propres manifests.
Agenty ne déclare aucun accès aux sites et aucun script de contenu, et fonctionne uniquement sur l’onglet que tu regardes au moment du clic, pour 2.2 MiB. Axiom.ai déclare toutes les URL HTTP et HTTPS sur 37.1 MiB. Magical déclare treize permissions dont clipboardRead — et c’est aussi la seule extension ici à fermer complètement la messagerie entrante. Table Capture ne déclare que quatre permissions, et injecte à document_start dans tous les cadres sur <all_urls> — le même plafond de correspondance que le nôtre atteint, mais plus tôt — plus userScripts sur demande. TexAu est la plus petite, et elle nomme le plus de cibles — quatorze motifs répartis sur treize propriétés distinctes. Elle n’est pas la seule à les nommer : Clip to Clay en déclare deux (clay.com et un site tiers), et Hexomatic ainsi que Clay for Chrome nomment leurs propres domaines. TexAu est la seule dont la liste nommée concerne surtout des sites d’autres personnes. Cinq des dix peuvent atteindre des fichiers sur ton disque, dont deux — Axiom.ai et la nôtre — sans jamais écrire file://.
Thunderbit, la nôtre, se situe à l’extrémité la plus large : <all_urls> à la fois pour l’accès aux hôtes et pour l’injection statique, plus debugger, qu’aucune autre extension de cet ensemble ne déclare. Elle est au comportement par défaut de Chrome qui autorise les messages de toute extension, et atteint file:// une fois le garde-fou utilisateur de Chrome activé.
Une déclaration est un plafond, pas un comportement, et rien de tout cela ne montre un usage abusif. Mais c’est publié, gratuit à vérifier, et l’écart entre les deux extrêmes est plus grand que tout ce qu’on voit sur les pages produit.
Essayer Thunderbit pour l’extraction de données web Get Started Free
FAQ
Une permission large signifie-t-elle que l’extension fait quelque chose de mal — et pourquoi un simple comptage ne suffit-il pas ?
Non, et parce qu’un simple comptage manque deux choses. <all_urls> signifie qu’une extension peut lire chaque page que tu visites ; cela ne dit rien sur ce qu’elle fait ni sur le fait que des données quittent ta machine, et un outil conçu pour extraire des données depuis n’importe quelle page ne peut réellement pas fonctionner avec une liste de domaines nommés. Le résultat observé ici est l’écart, pas une faute — établir le comportement réel exige une analyse du trafic à l’exécution, que cet audit n’a pas faite. Quant au comptage : les paramètres d’injection ne sont pas des permissions, donc Table Capture n’en déclare que quatre tout en injectant à document_start, dans all_frames, en ciblant <all_urls>. Et les optional_permissions n’apparaissent pas du tout dans la fenêtre d’installation — Table Capture peut demander userScripts à l’exécution, ce qui permet d’exécuter des scripts arbitraires fournis par l’utilisateur dans le contexte des pages, et Magical peut demander webRequest.
Laquelle demande le moins ?
Agenty : quatre permissions, aucune autorisation d’hôte, aucun script de contenu. Elle s’appuie sur activeTab, qui donne accès à l’onglet courant uniquement après un clic sur l’extension et seulement jusqu’à ce que tu changes de page. Hexomatic suit, avec deux permissions et des scripts de contenu limités à ses propres domaines.
Comment une extension peut-elle atteindre mes fichiers locaux sans déclarer file:// ?
Parce que <all_urls> inclut le schéma file:. Listly, Magical et Table Capture nomment explicitement des motifs file:// — Magical dans ses scripts de contenu et Table Capture dans web_accessible_resources. Axiom.ai et Thunderbit y accèdent via le joker sans le mentionner nulle part. http://*/* et https://*/* ne couvrent pas file://. Chrome maintient l’accès aux fichiers désactivé par défaut derrière un interrupteur propre à chaque extension ; la déclaration est donc une demande, pas une autorisation.
Qu’est-ce que externally_connectable, et pourquoi l’omettre est-il l’option la plus permissive ?
Cela nomme les origines web ou les ID d’extension autorisés à envoyer des messages au script d’arrière-plan d’une extension. Par défaut, quand la clé est absente, n’importe quelle extension peut se connecter et aucune page web ne le peut. Sept de ces dix l’omettent, Thunderbit compris. Quand la clé est présente, Hexomatic ouvre le canal extension à huit ID nommés ; Axiom.ai ouvre sept origines web tout en laissant le canal extension fermé ; Magical déclare des listes vides pour les deux, fermant ainsi les deux canaux.
Que déclare exactement le manifest de Thunderbit ?
<all_urls> pour l’accès aux hôtes et l’injection statique des scripts de contenu, dans all_frames à document_end ; 15.9 MiB répartis sur 78 fichiers ; et neuf chaînes dans le tableau des permissions. Huit sont des permissions reconnues : activeTab, debugger, offscreen, scripting, sidePanel, storage, tabGroups et tabs. commands est une clé de manifest de niveau supérieur et n’a aucun effet dans ce tableau. Aucune autre extension de cet ensemble ne déclare debugger. Thunderbit atteint aussi file:// via <all_urls> une fois le garde-fou d’accès aux fichiers de Chrome activé, et il omet externally_connectable. Le comportement à l’exécution n’a pas été exécuté, donc l’audit ne prétend pas dire quelles méthodes CDP ou de scripting l’extension appelle réellement.


