Elke Chrome-extensie bevat een manifest.json waarin een belangrijk deel van de browserrechten wordt vastgelegd: aangevraagde API’s, hostpatronen, statische content scripts, optionele machtigingen en toegestane externe verbindingen. Het is een openbaar bestand in het pakket dat je installeert. Het bewijst niet welke van die rechten de runtime-code daadwerkelijk gebruikt, wat de machine verlaat of welke accounttoegang via een aparte weblogin verloopt.
Ik heb de tien scraping- en browserautomatiserings-extensies die voor deze audit zijn geselecteerd doorgenomen, waaronder die van Thunderbit, omdat die van ons is. De spreiding is groot. Eén extensie declareert geen permanente toegang tot sites. Een andere verklaart dertien machtigingen, waaronder clipboardRead. Thunderbit is de enige extensie in deze set die debugger declareert: een brede CDP-koppelingsmogelijkheid met een ander risicoprofiel dan paginatoegang, OAuth of door de gebruiker aangeleverde scripts.
Dat is geen beschuldiging. Een brede machtiging is vaak de enige eerlijke manier om een bepaalde functie te bouwen, en een smalle kan simpelweg betekenen dat het product minder kan. Het punt is dat het verschil enorm is, openbaar is, en nooit in een vergelijkingstabel terechtkomt.
Hoe dit is gedaan
Elke extensie is als .crx gedownload via het eigen update-endpoint van Google — dezelfde URL die Chrome zelf gebruikt — en daarna uitgepakt en geanalyseerd. Er is geen extensie geïnstalleerd en er is geen extensiecode uitgevoerd. Dit is een lezing van een JSON-bestand.
De downloads zijn getemporiseerd op ongeveer één verzoek per twee seconden. Elke .crx, de SHA-256 en het geëxtraheerde manifest.json zijn bewaard als artefacten. Thunderbit is door precies hetzelfde script gegaan als de andere negen, niet via een apart pad, dus de rij is op exact dezelfde manier afgeleid.
De analyse gebruikt twee soorten bewijs en houdt die gescheiden:
- Gedrag dat statisch is gedeclareerd: hostpatronen en
content_scripts-vermeldingen, inclusiefmatches,run_atenall_frames. - Mogelijkheden die beschikbaar zijn voor runtime-code: API’s die worden genoemd in
permissionsofoptional_permissions. Deze verklaringen laten zien wat code zou kunnen opvragen of aanroepen, niet dat het dat ook doet.
Er wordt geen ranglijst van “meest krachtig” toegekend. debugger, userScripts, brede hosttoegang, OAuth-scopes, clipboardtoegang en externe messaging ontsluiten verschillende soorten data en vereisen verschillende voorwaarden. Ze met elkaar vergelijken vraagt om een threat model dat deze manifest-only audit niet levert.
De onderstaande groottes zijn uitgepakte totalen in MiB (2²⁰ bytes), opgeteld uit de ZIP-items.
Status per 2026-07-29. Extensies worden bijgewerkt; controleer opnieuw voordat je citeert.
Wat tien manifests declareren

Officiële referentie: Chrome's permission declaration guide.
| Extensie | Versie | Uitgepakt | Bestanden | Machtigingen | Site-toegang | Reikt tot file:// |
|---|---|---|---|---|---|---|
| Axiom.ai | 5.1.0 | 37.1 MiB | 232 | 8 | http://*/* + https://*/* | ✅ |
| Table Capture | 11.0.41 | 21.1 MiB | 115 | 4 (+3 optioneel) | <all_urls> | ✅ |
| Magical | 3.119.1 | 16.8 MiB | 395 | 13 (+2 optioneel) | <all_urls> | ✅ |
| Thunderbit (van ons) | 4.6.4 | 15.9 MiB | 78 | 8 herkende (+1 niet-herkende arraystring: commands) | <all_urls> | ✅ |
| Clay for Chrome | 1.0.0 | 6.3 MiB | 51 | 6 | *://*/* (injecteert alleen op het eigen domein) | — |
| Listly | 0.9.6 | 3.5 MiB | 84 | 7 | http://*/*, https://*/*, file:///*.html | ✅ |
| Hexomatic | 1.8.4 | 2.7 MiB | 37 | 2 | alleen eigen domeinen | — |
| Agenty | 2.9.7 | 2.2 MiB | 49 | 4 | geen gedeclareerd | — |
| Clip to Clay | 1.8.0 | 0.7 MiB | 16 | 4 | 2 benoemde domeinen | — |
| TexAu v2 | 1.6.6 | 0.3 MiB | 12 | 6 | 14 benoemde domeinen | — |
Twee andere stonden ook op de kandidatenlijst en ontbreken in de tabel, om redenen die op zichzelf het vermelden waard zijn.
De spreiding is een ontwerpkeuze, geen gevolg van formaat
Agenty declareert geen host permissions en levert helemaal geen content scripts mee. De vier machtigingen zijn activeTab, scripting, identity en identity.email. activeTab is de smalle variant: die geeft toegang tot het huidige tabblad pas nadat je op de extensie klikt, en alleen totdat je naar een andere pagina gaat. Er draait niets op je pagina’s tenzij je het zelf activeert. En dat alles in 2.2 MiB.
Axiom.ai declareert http://*/* en https://*/*, injecteert content scripts die overeenkomen met <all_urls>, en pakt uit naar 37.1 MiB verspreid over 232 bestanden — zeventien keer zo groot als Agenty, met permanente toegang tot elke pagina die je bezoekt.
Hexomatic zit in hetzelfde kamp als Agenty: twee machtigingen (storage, tabs), geen host permissions, en content scripts beperkt tot de eigen twee domeinen.
Clay for Chrome is een derde vorm die je apart moet bekijken: het declareert *://*/* als host permission, maar injecteert content scripts alleen op het eigen domein. De permanente mogelijkheid is breed; het automatische gedrag is smal. Een tabel met alleen machtigingen gooit die twee op één hoop.
Vijf van de tien kunnen bestanden op je schijf bereiken
file:/// is geen website. Het is je lokale bestandssysteem, weergegeven in een browsertabblad — een PDF die je opende, een HTML-export, een gedownloade factuur.
Officiële referentie: Chrome match-pattern documentation.
Drie extensies zeggen het expliciet. Twee bereiken het zonder het te benoemen: <all_urls> omvat het file:-schema.
| Extensie | Hoe het file:// bereikt | Noemt file:// in het manifest? | Waar |
|---|---|---|---|
| Magical | matcht file:///* — elk lokaal bestand dat Chrome rendert, niet alleen HTML — in vier van zijn zes content-scriptvermeldingen | ✅ | content scripts en web_accessible_resources |
| Listly | matcht file:///*.html | ✅ | content scripts |
| Table Capture | all_urls-content scripts, en het noemt het schema ook expliciet | ✅ | web_accessible_resources |
| Axiom.ai | puur vanwege de wildcard <all_urls> | — | nergens |
| Thunderbit (van ons) | puur vanwege de wildcard <all_urls> | — | nergens |
http://*/* en https://*/* dekken file:// niet; <all_urls> en *://*/* verschillen hier ook van.
De vijf hier zijn de extensies waarvan de declaraties het schema via de ene of de andere route bereiken — niet vanwege de wildcardvorm die ze kozen.
Chrome zet dit alles achter een per-extensie-toggle “Allow access to file URLs”, die standaard uit staat, dus de declaratie is een verzoek en geen automatische toekenning. Vijf van de tien is de eerlijke telling, en twee van die vijf schrijven nooit file:// ergens in hun manifest: Axiom.ai en die van ons.
Deze telling telt ook web_accessible_resources mee, niet alleen content scripts en host permissions. Table Capture noemt daar file://*/*; dat blok weglaten zou het onterecht plaatsen bij extensies waarvan het manifest bestanden bereikt zonder het schema te benoemen.
Machtigingen die je pas ziet als ze worden opgevraagd

optional_permissions worden vooraf gedeclareerd maar pas tijdens runtime aangevraagd, dus ze verschijnen niet in de installatiewaarschuwing. Twee extensies gebruiken ze, en één daarvan is relevant.
| Extensie | optional_permissions | De relevante |
|---|---|---|
| Table Capture | userScripts, downloads, identity | userScripts kan door de gebruiker aangeleverde scripts in paginacontext laten draaien nadat Chrome’s gebruikerspoort is geactiveerd |
| Magical | downloads, webRequest | webRequest observeert netwerkverkeer |
userScripts is niet zichtbaar tot het wordt opgevraagd, en dus onzichtbaar voor iedereen die alleen een machtigingentelling leest.
Het heeft ook een extra poort waar de rest van de machtigingen in deze audit niet over beschikken, en die wegpoetsen zou het beeld vertekenen. Alleen het declareren van userScripts is niet genoeg om het te gebruiken: Chrome vereist eerst een expliciete gebruikersactie. Vóór Chrome 138 was dat Developer Mode, wereldwijd ingeschakeld via chrome://extensions. Vanaf Chrome 138 is het een per-extensie-toggle Allow User Scripts op de detailpagina van die extensie, standaard uit. Voor een gewone installatie is de mogelijkheid dus gedeclareerd maar inert. De precieze claim is voorwaardelijk: Table Capture kan de userScripts-API beschikbaar maken nadat de gebruiker Chrome’s poort activeert. Deze audit heeft niet gemeten hoe vaak gebruikers die instellingenpagina bezoeken of de toggle inschakelen.
Geen van beide is verborgen; allebei staan in het manifest. Een tabel die het optionele blok negeert, doet twee producten tekort.
Injectietiming, niet alleen scope
Hoe een content script wordt geïnjecteerd krijgt vaak geen aandacht, maar verandert het beeld. document_start is de vroegste hook die Chrome biedt; all_frames bereikt third-party embeds.
Alles in deze set dat statisch in alle frames injecteert, gesorteerd op de gedeclareerde timing:
| Extensie | run_at | all_frames | Content-script matchpatroon |
|---|---|---|---|
| Table Capture | document_start | ✅ | <all_urls> |
| Listly | document_start | ✅ | file:///*.html plus alle http en https |
| Axiom.ai | document_start | ✅ | alleen eigen domeinen |
| Clay for Chrome | document_start | ✅ | alleen eigen domeinen |
| Thunderbit (van ons) | document_end | ✅ | <all_urls> |
| Magical | document_idle | ✅ | file:///* plus brede http en https |
| TexAu | document_idle (niet ingesteld) | ✅ | veertien benoemde patronen |
Table Capture en Listly gebruiken de vroegste hook over brede matchpatronen. Axiom.ai en Clay for Chrome gebruiken dezelfde timing, maar alleen op hun eigen domeinen — dezelfde agressiviteit, smalle doelgroep.
Voor statische declaraties is <all_urls> plus all_frames het maximum aan match-breedte, en zowel Table Capture als Thunderbit zitten daar. Hun gedeclareerde timing verschilt: Table Capture gebruikt document_start; Thunderbit’s statische content script gebruikt document_end. Runtime-API’s zijn een aparte categorie en kunnen niet uit deze tabel worden afgeleid.
Een machtigingentelling is een slechte samenvattende statistiek. Table Capture declareert vier machtigingen — minder dan de meeste hier — en injecteert op document_start in alle frames op <all_urls>, plus userScripts op verzoek.
Wie de extensie mag benaderen
externally_connectable bepaalt welke webpagina’s of andere extensies direct berichten naar de background script van een extensie mogen sturen. De standaard is contra-intuïtief.
De sleutel weglaten is de ruimhartige instelling. Chrome’s standaard wanneer externally_connectable ontbreekt, is dat elke extensie mag verbinden, terwijl geen enkele webpagina dat mag. Het declareren ervan is hoe je beperkt.
Als je het zo leest, draait de tabel om:
| Extensie | externally_connectable-declaratie | Wie kan berichten sturen |
|---|---|---|
| Agenty | weggelaten | Ruimhartige standaard — elke extensie mag verbinden, geen webpagina mag |
| Clay for Chrome | weggelaten | Ruimhartige standaard — elke extensie mag verbinden, geen webpagina mag |
| Clip to Clay | weggelaten | Ruimhartige standaard — elke extensie mag verbinden, geen webpagina mag |
| Listly | weggelaten | Ruimhartige standaard — elke extensie mag verbinden, geen webpagina mag |
| Table Capture | weggelaten | Ruimhartige standaard — elke extensie mag verbinden, geen webpagina mag |
| TexAu | weggelaten | Ruimhartige standaard — elke extensie mag verbinden, geen webpagina mag |
| Thunderbit (van ons) | weggelaten | Ruimhartige standaard — elke extensie mag verbinden, geen webpagina mag |
| Hexomatic | acht extensie-ID’s en zes weborigins | Opent beide kanalen vanaf een gesloten basis |
| Axiom.ai | zeven weborigins, geen ids | Extensie-kanaal gesloten, zeven webpagina’s geopend |
| Magical | {"ids": [], "matches": []} | De enige extensie hier die beide kanalen expliciet sluit |
Chrome’s regel heeft twee niveaus. Volgens de manifestreferentie:
| Situatie | Wie mag verbinden |
|---|---|
| de hele sleutel is afwezig | "all extensions can connect, but no web pages can connect" |
sleutel aanwezig, ids niet ingesteld of [] | "no extensions or apps can connect" |
sleutel aanwezig, matches niet ingesteld of [] | "no web pages can connect" |
De ruimhartige standaard hangt dus af van de afwezigheid van de hele sleutel. Zodra de sleutel er is, beginnen beide subvelden gesloten en vergroot het benoemen van waarden elk kanaal.
Axiom.ai declareert de sleutel alleen met matches. De ids zijn dus niet ingesteld, wat betekent dat geen enkele extensie ermee kan communiceren — het extensiekanaal is gesloten, niet open gelaten. Wat wel open is, zijn zeven weborigins, waarvan er maar één een Axiom-domein is: twee zijn niet-toerekenbare derden (*://*.tgwc.space/*, *://*.bitmachine.co.uk/*) en de rest zijn localhost, 0.0.0.0, een Google-APIs-host en één groot sociaal platform dat het niet beheert.
Hexomatic opent zijn extensiekanaal naar acht benoemde ID’s. Met de sleutel aanwezig is de basis nul extensies; acht benoemen maakt daar acht van. De zes matches verbreden het andere kanaal vanaf nul, en twee daarvan zijn http://localhost:8000/* en http://localhost:3000/* via gewoon HTTP — alles wat op die poorten op de machine van de gebruiker antwoordt valt binnen de allowlist.
Zeven van de tien laten de sleutel helemaal weg, inclusief die van ons, en juist zij zitten op de permissieve standaard voor extensie-naar-extensiemessaging. Twee extensies sluiten dat kanaal: Magical expliciet met ids: [], en Axiom.ai door de sleutel te declareren en ids nooit te noemen. Magical is de enige die beide sluit.
Die laatste zin is precies waarom je manifests moet lezen in plaats van alleen machtigingen tellen. Dezelfde extensie kan op de ene as breed zijn en op een andere as het strengst van allemaal.
De as die niemand telt: OAuth-scopes
Een manifest kan een oauth2-blok bevatten, en de scopes daarin geven toegang tot je accounts bij andere bedrijven — een ander soort bereik dan alles hierboven, en een dat geen enkele machtigingentelling weerspiegelt.
Officiële referentie: Google OAuth 2.0 scope list.
| Extensie | Aangevraagde oauth2-scopes |
|---|---|
| Axiom.ai | openid, email, profile, auth/drive, auth/spreadsheets |
| Table Capture | auth/spreadsheets, auth/userinfo.email |
| Agenty | openid, email, profile |
| De andere zeven, inclusief die van ons | geen gedeclareerd |
https://www.googleapis.com/auth/drive is de brede variant. Google heeft een smallere drive.file-scope die alleen toegang geeft tot bestanden die de app zelf maakt of die de gebruiker expliciet kiest; auth/drive is bekijken, bewerken, aanmaken en verwijderen binnen de hele Drive van de gebruiker. auth/spreadsheets heeft dezelfde vorm voor elke spreadsheet die het account kan bereiken.
Zowel Axiom.ai als Table Capture koppelen een Google-accountscope aan <all_urls>-paginatoegang.
Twee beperkingen op wat deze tabel bewijst. Een scope wordt aangevraagd, niet toegekend — Google toont een toestemmingsscherm en de gebruiker kan weigeren, en de extensie hoeft de API nooit aan te roepen. En het manifest ziet alleen OAuth via Chrome’s identity-flow; een extensie die je in plaats daarvan naar een web-inlogpagina stuurt, zou hier niets declareren. De zeven nullen betekenen “niet aangevraagd in dit bestand”, niet “geen toegang tot je Google-account” — ook die van ons, en daarom rapporteren we deze as in plaats van haar als smal te claimen.
Onze eigen extensie, op dezelfde schaal
Thunderbit 4.6.4 is door dezelfde manifestparser gehaald als de andere negen. Het pakket is 15.9 MiB uitgepakt over 78 bestanden.
Statisch gedeclareerd gedrag: <all_urls> komt voor in host permissions en in content-script matches. Het statische script draait in all_frames op document_end. Omdat <all_urls> ook file: omvat, kan het manifest lokale bestanden bereiken nadat de gebruiker Chrome’s bestandstoegang-toggle heeft ingeschakeld. Thunderbit laat ook externally_connectable weg, dus Chrome’s standaard staat berichten toe van elke extensie maar niet van webpagina’s.
Runtime-capaciteitsgrens: de permissions-array bevat negen strings: activeTab, commands, debugger, offscreen, scripting, sidePanel, storage, tabGroups en tabs. Chrome herkent er acht als machtigingen; commands is een sleutel op hoofdniveau van het manifest en heeft geen effect als vermelding in deze array. Thunderbit is de enige extensie in deze set die debugger declareert, wat CDP aan een tab kan koppelen. Het manifest maakt ook scripting beschikbaar voor runtime-registratie. Die API’s creëren mogelijkheden die verder gaan dan de statische document_end-rij, maar een manifestlezing kan niet vaststellen dat Thunderbit een bepaalde CDP-methode aanroept of een script op een eerder moment registreert.
Dat onderscheid blokkeert een aantal verleidelijke maar onjuiste vergelijkingen. Het ontbreken van een smallere cookies-machtiging begrenst niet wat code met debugger zou kunnen zien. Het ontbreken van clipboardRead bewijst niet dat clipboardtoegang onmogelijk is. Omgekeerd is het aanwezig zijn van debugger geen bewijs dat die routes ook echt worden gebruikt. Voor een antwoord op die vragen heb je broninspectie of runtime-tracing nodig, en geen van beide is hier uitgevoerd.
Op dit instrument is Thunderbit breed qua statische site-toegang, uniek in deze set door debugger te declareren, en staat het op Chrome’s standaard voor extensie-naar-extensiemessaging. Er bestaat geen eenduidige “sterkste” rangschikking, omdat deze audit geen gemeenschappelijk threat model levert voor CDP, OAuth, userScripts, clipboard en hosttoegang.
Het ingetogen ontwerp dat niemand vermarkt
TexAu is 0.3 MiB — hier de kleinste met een factor twee — en het noemt veertien specifieke sites in plaats van een wildcard te gebruiken: sociale netwerken, een ontwikkelaarsplatform, publicatieplatforms, een chatproduct, een aanbieder van zakelijke data en het eigen domein. De content scripts komen exact overeen met diezelfde veertien.
Je kunt dit manifest lezen en precies weten waar de extensie actief is. Het is ook een productverklaring — de targetlijst zegt duidelijker waar het hulpmiddel voor bedoeld is dan de marketing dat doet.
De trade-off is reëel: een benoemde lijst kan geen site scrapen die er niet op staat, en elke nieuwe target vereist een release. Maar “veertien benoemde domeinen” en “elke URL die bestaat” zijn heel verschillende proposities, en slechts één daarvan is leesbaar.
Twee producten die niet waren wat de lijst zei
De extensie van Captain Data wordt niet openbaar gedistribueerd. Het update-endpoint van Google geeft HTTP 204 met een lege body voor de extensie-ID — de reactie van iets dat de store niet anoniem uitserveert. De listingpagina daarentegen werd wel anoniem geserveerd — HTTP 200, 509.829 bytes. Wat de capture daar niet in kon vinden, waren een versienummer, een laatstbijgewerkte datum of een installatietelling; de eigen notities van het script zeggen dat een nul daar zwak bewijs is, en er werd geen inlogmuur waargenomen. De ID is echt en first-party, dus distributie via link of niet-vermelding is de meest waarschijnlijke lezing, maar ik kon dat niet onderscheiden van delisting en ga dus niet gokken.
Dataflow Kit heeft helemaal geen Chrome-extensie. Hun site beschrijft een gehoste webapp met point-and-click selectie en een REST API. Toch was het meegenomen op een shortlist voor Chrome-extensies — en zo worden dit soort lijsten meestal opgebouwd.
Veroudering en bereik, omdat beide gratis te controleren zijn
Store-metadata geeft productselectiecontext naast machtigingen. Dezelfde velden zijn voor elke extensie vastgelegd op 2026-07-30.
| Extensie | Store-versie | Laatst bijgewerkt | Installatiebucket |
|---|---|---|---|
| Thunderbit (van ons) | 4.6.4 | 28 juli 2026 | 200.000 |
| Listly | 0.9.6 | 25 juli 2026 | 100.000 |
| Axiom.ai | 5.1.0 | 20 juli 2026 | 100.000 |
| Table Capture | 11.0.41 | 26 juni 2026 | 200.000 |
| Magical | 3.119.1 | 4 april 2026 | 200.000 |
| Agenty | 2.9.7 | 8 februari 2026 | 10.000 |
| TexAu | 1.6.6 | 20 augustus 2025 | 7.000 |
| Clay for Chrome | 1.0.0 | 9 april 2025 | 10.000 |
| Clip to Clay | 1.8.0 | 8 april 2025 | 1.000 |
| Hexomatic | 1.8.4 | 6 september 2024 | 3.000 |
| Captain Data | — | — | niet openbaar geserveerd |
Drie producten zijn al meer dan een jaar niet uitgebracht, en Hexomatic bijna twee jaar niet. Voor extensies is dat belangrijker dan voor libraries: Chrome brengt ongeveer elke vier weken een stabiele release uit en het extensieplatform verandert ondertussen zelf ook door. userScripts verschoof zijn gebruikerspoort in Chrome 138; een extensie die voor het laatst in 2024 verscheen, is gebouwd tegen een andere set regels dan de browser die die nu afdwingt.
Twee dingen die deze tabel niet is. Installatietellingen zijn door Google in buckets ingedeeld — 1.000 / 3.000 / 7.000 / 10.000 / 100.000 / 200.000 — dus ze vergelijken ordegottes en niets fijner, en verschillende producten noemen in hun eigen marketing grotere aantallen. Een recente datum is een feit over uitbrengen, geen oordeel over onderhoudskwaliteit of risicoprofiel van machtigingen.
Eén nuttig bijproduct: de store-versie komt overeen met de manifestversie in elk van de tien geanalyseerde pakketten. De CRX-bestanden die deze audit heeft geparsed zijn dus de pakketten die de store vandaag serveert, niet verouderde kopieën.
Versheid beïnvloedt hoeveel vervolgonderzoek een selectie verdient; het verandert de semantiek van het manifest niet. Een extensie met benoemde domeinen die een jaar geleden voor het laatst is bijgewerkt, kan nog steeds minder paginagebied blootstellen dan een wildcard-extensie die gisteren is uitgebracht. Het nieuwere pakket kan operationeel nog steeds de betere keuze zijn als het Chrome-wijzigingen snel bijhoudt. Gebruik voor een shortlist de store-datum om te bepalen wat opnieuw getest moet worden, en het manifest om te bepalen wat een diepere capaciteitsreview vereist. Maak van die twee kolommen geen enkele score.
Wat een manifest je niet vertelt
Een gedeclareerde machtiging is een bovengrens, geen gedrag. <all_urls> betekent dat een extensie mag lezen wat er op elke pagina staat. Het betekent niet dat het dat ook doet, of dat er iets van je machine weggaat. Vaststellen wat er werkelijk gebeurt vraagt om het volgen van netwerkverkeer tijdens runtime — ander werk, hier niet gedaan, en niets hierboven moet worden gelezen als bewijs van misbruik.
Gerelateerde review: Chrome extension testability experiment.
Nog drie grenzen:
- Chrome begrenst veel hiervan. Bestandstoegang staat standaard uit;
activeTabis bewust smal; optionele machtigingen vereisen een runtime-prompt; gebruikers zien bij installatie een machtigingentabel. - Brede machtigingen zijn vaak noodzakelijk. Een tool met als taak “haal een tabel van elke pagina die je bezoekt” kan niet werken vanuit een allowlist met alleen benoemde domeinen. Smalle scope is soms discipline en soms gewoon een kleiner product.
- Eén versie, één dag. Alle cijfers komen uit het pakket dat op 2026-07-29 werd geserveerd.
Materiële correcties in de analyse
De gepubliceerde tellingen gebruiken drie regels die je bij een snelle manifestparser makkelijk verkeerd toepast. Ten eerste omvat <all_urls> het file:-schema, maar Chrome houdt daadwerkelijke bestandstoegang achter een door de gebruiker bediende toggle. Ten tweede moet web_accessible_resources.matches samen met content scripts en host permissions worden bekeken; daar noemt Table Capture expliciet file://*/*. Ten derde heeft externally_connectable verschillende defaults afhankelijk van of de hele sleutel ontbreekt of de sleutel bestaat met een leeg subveld. De tabellen hierboven passen die regels consequent toe.
Thunderbit’s machtigingentotaal maakt bovendien onderscheid tussen ruwe strings en herkende Chrome-machtigingen. De array bevat negen items, maar commands hoort op het hoogste niveau, dus de effectieve telling hier is acht herkende machtigingen plus één niet-herkende string. Tot slot zijn statische content_scripts-declaraties geen bewijs dat code scripting.registerContentScripts of een CDP-methode aanroept. Die mogelijkheden vallen alleen onder runtime-capaciteit, nooit onder waargenomen gedrag. De ruwe manifests, CRX-hashes en parseroutput vormen het auditspoor voor deze normalisaties, zodat lezers de tekst niet op goed vertrouwen hoeven te nemen.
Voor een echte installatiedecisie vergelijk je minstens vier dimensies apart: welke pagina’s standaard binnen scope vallen, welke expliciete gebruikersactie meer bereik vrijgeeft, welke browser- of account-API’s beschikbaar komen, en welke externe aanroepen de extensie mogen berichten sturen. Agenty’s activeTab-model, Table Capture’s afgeschermde userScripts, Axiom.ai’s Drive-scope en Thunderbit’s debugger-declaratie zijn geen punten op één lineaire schaal. Het zijn verschillende antwoorden op verschillende beveiligingsvragen.
Hier is die vergelijking toegepast op vier bewust verschillende ontwerpen:
| Extensie | Paginabereik zichtbaar in het manifest | Extra poort | Niet-pagina-capaciteit in deze audit | Postuur voor externe aanroeper |
|---|---|---|---|---|
| Agenty | geen host permission of statisch content script | gebruiker activeert activeTab op het huidige tabblad | Chrome identity-machtigingen | sleutel weggelaten: elke extensie mag verbinden, geen webpagina mag |
| Table Capture | statische scripts op <all_urls> in alle frames op document_start | bestandstoegang staat standaard uit; userScripts heeft Chrome’s aparte gebruikerspoort nodig | optionele userScripts, downloads en identity | sleutel weggelaten: elke extensie mag verbinden, geen webpagina mag |
| Axiom.ai | HTTP- en HTTPS-wildcardtoegang; statische scripts op document_start op de eigen domeinen | OAuth-toestemming voor aangevraagde Google-scopes | Drive- en Sheets-OAuth-scopes gedeclareerd | extensie-aanroepers gesloten; zeven weborigins geopend |
| Thunderbit | <all_urls> hosttoegang en statische scripts in alle frames op document_end | bestandstoegang staat standaard uit; het koppelen van debugger heeft door Chrome gecontroleerd, zichtbaar gebruikersgedrag | debugger, scripting, tabs en verwante browser-API’s gedeclareerd | sleutel weggelaten: elke extensie mag verbinden, geen webpagina mag |
Ook deze tabel levert nog geen winnaar op. Agenty’s smalle permanente paginatoegang zegt niets over wat de backend met ingestuurde data doet. Axiom.ai’s accountscopes zijn niet vergelijkbaar met een extensie die de huidige pagina leest. Table Capture’s userScripts-declaratie is inert totdat de gebruiker de aparte poort activeert. Thunderbit’s debugger-machtiging opent een brede browsercontrolevlakte, maar het manifest laat niet zien welke CDP-domeinen of -methoden de code aanroept. Elke rij vertelt je wat je hierna moet inspecteren: runtime-netwerkverkeer, broncode, toestemmingsflow of browser-API-traces.

Diezelfde scheiding is belangrijk bij het lezen van Chrome’s installatiewaarschuwing. Een rauwe machtigingentelling kan timing, frame-bereik, OAuth-scope, web_accessible_resources of een weggelaten externally_connectable-sleutel niet laten zien. Omgekeerd is een brede declaratie geen bewijs van verzameling of exfiltratie. De bruikbare uitkomst van een manifest-audit is een geprioriteerd runtime-testplan: identificeer het datavlak, noteer de gebruikerspoort en observeer vervolgens of het gedeclareerde pad ook echt wordt gebruikt.
Hoe je je eigen kunt lezen
Gerelateerde review: browser automation guide.
chrome://extensions→ Details toont de verleende site-toegang en laat je die op on click zetten voor alles wat geen permanente toegang nodig heeft. Daarmee beperk je de site-toegangshelft van wat hierboven staat. Het verandert niets aan inkomende messaging (externally_connectablebereikt de service worker ongeacht), of browser-level machtigingen.
Thunderbit’sdebugger-declaratie is hier relevant. Chrome’s eigen beveiligingsdocumentatie voor extensies zegt dat de debugger-API “in some cases also sidestep other typical restrictions, such as host permissions or file access”, dus site-toegang op “on click” zetten begrenst niet wat het kan bereiken. Die instelling raakt ook niettabs,webNavigation,clipboardRead,downloadsof iets inoptional_permissions.- Voor het ruwe bestand staat het pakket onder Chrome’s map
Extensions/<id>/<version>/. Lees zes velden:permissions,optional_permissions,host_permissions,content_scripts(dematches,run_atenall_framesdaarin),externally_connectable— met de herinnering dat een afwezige sleutel ruimhartig is voor extensie-aanroepers — enweb_accessible_resources, waarvanmatchesschema’s kunnen noemen die de content scripts nooit noemen. Thunderbit’s laatste veld bevat twee<all_urls>-vermeldingen dieindex.htmlen twee gebundelde scripts voor elke origin beschikbaar maken, metuse_dynamic_url: false, waardoor een pagina kan testen of die stabiele extensie-URL’s resolven. - Controleer de laatst bijgewerkte datum van de listing tegen de huidige Chrome-versie.
Openbaarmaking en resources: dit artikel is gepubliceerd door Thunderbit, waarvan de extensie in dezelfde tabel en parser is opgenomen. Onze open-source scraper pillar behandelt niet-extensie tools.
Probeer Thunderbit voor webdata-extractie
De korte versie
Tien scraping- en automatiserings-extensies, inclusief die van ons, zijn gelezen vanuit hun eigen manifests.
Agenty declareert geen site-toegang en geen content scripts, en werkt alleen op het tabblad dat je bekijkt wanneer je erop klikt, in 2.2 MiB. Axiom.ai declareert elke HTTP- en HTTPS-URL verspreid over 37.1 MiB. Magical declareert dertien machtigingen, waaronder clipboardRead — en is ook de enige extensie hier die inkomende messaging volledig sluit. Table Capture declareert slechts vier machtigingen, en injecteert op document_start in alle frames op <all_urls> — hetzelfde matchplafond dat ook die van ons bereikt, maar dan eerder — plus userScripts op verzoek. TexAu is de kleinste, en het noemt de meeste targets — veertien patronen over dertien verschillende eigenschappen. Het is niet de enige die ze noemt: Clip to Clay declareert er twee (clay.com en één third-party site), en Hexomatic en Clay for Chrome noemen hun eigen domeinen. TexAu is de enige waarvan de benoemde lijst vooral bestaat uit sites van anderen. Vijf van de tien kunnen bestanden op je schijf bereiken, waarvan twee — Axiom.ai en die van ons — zonder ooit file:// te schrijven.
Thunderbit, van ons, zit aan de brede kant: <all_urls> voor zowel hosttoegang als statische injectie, plus debugger, wat geen enkele andere extensie in deze set declareert. Het staat op Chrome’s standaard die berichten van elke extensie toestaat, en het kan file:// bereiken nadat Chrome’s gebruikerspoort voor bestandstoegang is geactiveerd.
Een declaratie is een bovengrens, geen gedrag, en niets hiervan toont misbruik. Maar het is openbaar, gratis te controleren, en de spreiding tussen de twee uiteinden is groter dan wat je op de productpagina’s ziet.
Probeer Thunderbit voor webdata-extractie Get Started Free
FAQ’s
Betekent een brede machtiging dat de extensie iets verkeerd doet — en waarom is het tellen van machtigingen niet genoeg?
Nee, en omdat tellen twee dingen mist. <all_urls> betekent dat een extensie mag lezen wat er op elke pagina staat; het zegt niets over wat het doet of dat er iets van je machine weggaat, en een tool die data van elke pagina moet halen kan nu eenmaal niet werken vanuit een allowlist met alleen benoemde domeinen. De bevinding is de spreiding, niet wangedrag — echt gedrag vaststellen vraagt runtime-analyse van verkeer, en die is hier niet gedaan. Over de telling: injectie-instellingen zijn geen machtigingen, dus Table Capture declareert er vier terwijl het op document_start, in all_frames, op <all_urls> injecteert. En optional_permissions verschijnen niet eens in de installatiewaarschuwing — Table Capture kan userScripts op runtime aanvragen, wat het draaien van willekeurige door gebruikers aangeleverde scripts in paginacontext mogelijk maakt, en Magical kan webRequest aanvragen.
Welke vraagt het minst?
Agenty: vier machtigingen, geen host permissions, geen content scripts. Het leunt op activeTab, wat toegang geeft tot het huidige tabblad pas nadat je op de extensie klikt en alleen totdat je weg navigeert. Hexomatic komt daarna, met twee machtigingen en content scripts die beperkt zijn tot de eigen domeinen.
Hoe kan een extensie mijn lokale bestanden bereiken zonder file:// te declareren?
Omdat <all_urls> het file:-schema omvat. Listly, Magical en Table Capture noemen file://-patronen expliciet — Magical in zijn content scripts en Table Capture in web_accessible_resources. Axiom.ai en Thunderbit bereiken het via de wildcard zonder het ergens te noemen. http://*/* en https://*/* dekken file:// niet. Chrome laat bestandstoegang standaard uit staan achter een per-extensie-toggle, dus de declaratie is een verzoek en geen toekenning.
Wat is externally_connectable, en waarom is het weglaten ervan de ruimhartige optie?
Het benoemt de weborigins of extensie-ID’s die naar de background script van een extensie mogen berichten. Chrome’s standaard wanneer de sleutel afwezig is, is dat elke extensie mag verbinden en geen enkele webpagina dat mag. Zeven van deze tien laten het weg, inclusief Thunderbit. Met de sleutel aanwezig opent Hexomatic het extensiekanaal naar acht benoemde ID’s; Axiom.ai opent zeven weborigins terwijl het extensiekanaal gesloten blijft; Magical declareert lege lijsten voor beide en sluit zo beide kanalen.
Wat declareert Thunderbit’s eigen manifest?
<all_urls> voor hosttoegang en statische content-scriptinjectie, in all_frames op document_end; 15.9 MiB over 78 bestanden; en negen strings in de machtigingenarray. Acht daarvan zijn herkende machtigingen: activeTab, debugger, offscreen, scripting, sidePanel, storage, tabGroups en tabs. commands is een sleutel op het hoogste niveau van het manifest en heeft in die array geen effect. Geen enkele andere extensie in deze set declareert debugger. Thunderbit bereikt ook file:// via <all_urls> nadat Chrome’s bestandstoegangspoort is geactiveerd, en het laat externally_connectable weg. Runtime-gedrag is niet uitgevoerd, dus de audit claimt niet welke CDP- of scriptingmethoden de extensie daadwerkelijk aanroept.


