A forensic reference for those who give a damn


I have spent the better part of two decades fighting for digital privacy - from bankrupting spyware companies to filing criminal complaints against corporations who thought they were above the law. In all that time, one thing has become abundantly clear to me - the browser you are using right now is almost certainly betraying you.

This is not a textbook and it is not a research paper. It is a comprehensive, technically accurate and forensically useful reference covering every known client-side privacy vulnerability in Google Chrome - and more importantly, how to detect each one using a Chrome extension built with Manifest V3 and installed in developer mode with full permissions including the debugger API.

I write this because I believe that knowledge is the first step towards freedom. If we do not understand how we are being tracked, profiled and exploited then we have no hope of stopping it. So let us begin.

It is important to note that I used AI to assist in my research (or rather compliment the 20+ years of direct experience I have with these issues) so I apologise for any inaccuracies in advance and ask that you reach out to me directly if you find any (so I can correct them). I have provided a significant list of references at the end of the article.


Part 1: Browser Fingerprinting - They Know Your Machine Better Than You Do

There are at least thirty distinct fingerprinting techniques that work in Chrome right now, today, as you read this. Not theoretical attacks from academic papers that might work under laboratory conditions - real, production techniques deployed on millions of websites to identify and track you without your knowledge or consent [1][2].

Chrome ships almost no built-in anti-fingerprinting defences. Let me say that again because it matters - Google's browser, the most popular browser in the world, does essentially nothing to prevent websites from building a unique profile of your device. Brave has farbling [3]. Firefox has privacy.resistFingerprinting [4]. Chrome has nothing. Google's Privacy Sandbox was discontinued in April 2025 without shipping a single fingerprinting-specific mitigation [5][6]. The Privacy Budget proposal which would have limited the total amount of entropy a site could collect per visit was abandoned entirely [7].

So it falls to us - to extension developers, to researchers, to those of us who refuse to accept that this is just the way things are.

How a Manifest V3 Extension Intercepts Fingerprinting

Before I get into the individual techniques, you need to understand the detection architecture because without this foundation the rest is just a list of grievances.

An MV3 extension has four layers of interception available to it, each covering different parts of the fingerprinting surface.

Main-world content scripts are your primary weapon. Since Chrome 111, you can declare "world": "MAIN" with "run_at": "document_start" in your manifest and your code runs directly in the page's JavaScript context before any page script executes [8][9]. This means you can wrap prototypes with Proxy objects - replace HTMLCanvasElement.prototype.toDataURL with a proxy that logs calls, captures stack traces via new Error().stack and optionally injects noise before forwarding to the original. Communication back to the extension uses CustomEvent dispatch on document, relayed through an isolated-world content script to the background service worker via chrome.runtime.sendMessage.

Chrome DevTools Protocol via chrome.debugger gives you deeper reach. Page.addScriptToEvaluateOnNewDocument injects monitoring code before any frame's scripts run, surviving navigations [10][11]. Runtime.addBinding creates named functions callable from page context that fire events in the extension - more reliable than postMessage. And critically, Target.setAutoAttach with flatten: true attaches to child targets including cross-origin iframes and Web Workers - the only way to intercept fingerprinting inside workers where content scripts simply cannot go [12].

One UX caveat worth flagging up front - the moment your extension calls chrome.debugger.attach, Chrome displays a persistent banner reading "[extension name] started debugging this browser" at the top of the tab and disables DevTools on that target for as long as the debugger is attached. This is by design and cannot be suppressed. For a forensic tool this is acceptable (arguably desirable - it makes the interception visible to the user) but it rules out silent deployment and will surprise anyone building on this pattern for the first time.

Network observation uses non-blocking chrome.webRequest listeners which remain fully functional in MV3 [13]. These monitor Client Hints headers and requests to known fingerprinting endpoints. declarativeNetRequest rules can block known fingerprinting script URLs and strip tracking headers [14].

The limitation you need to be aware of is this - content scripts cannot inject into Web Workers or Service Workers. Only CDP via the debugger API with Target.setAutoAttach can monitor worker contexts. Sophisticated fingerprinters can also detect your hooks by calling Function.prototype.toString on patched methods - you need to wrap toString as well to return "[native code]".

Now let us look at every single technique they are using against us.

Canvas Fingerprinting

This is the big one - found on roughly 12.7% of the top 20,000 websites according to a 2025 ACM study [15]. The technique draws text with fillText triggering OS-specific font rasterisation, geometric shapes with arc and bezierCurveTo exposing GPU anti-aliasing differences, and semi-transparent overlays testing alpha compositing precision. Then it extracts the pixels via toDataURL('image/png') and hashes the result [16].

FingerprintJS's open-source implementation renders two images - a text image including emoji and a geometry image - then performs a stability check by rendering twice to detect browser-injected noise [17]. The 2022 DrawnApart research demonstrated that even nominally identical GPU units produce different output due to manufacturing variations [18].

Chrome applies no mitigation whatsoever. Canvas fingerprinting works fully. The APIs you need to intercept are HTMLCanvasElement.prototype.toDataURL, .toBlob and CanvasRenderingContext2D.prototype.getImageData.

WebGL Fingerprinting

The WEBGL_debug_renderer_info extension exposes UNMASKED_VENDOR_WEBGL and UNMASKED_RENDERER_WEBGL, returning strings like "ANGLE (NVIDIA, GeForce RTX 4090 Direct3D11 vs_5_0 ps_5_0, D3D11)" [19][20]. Beyond renderer strings, getParameter() enumeration collects over 30 GPU capability values - MAX_TEXTURE_SIZE alone reveals hardware class [21]. getSupportedExtensions() returns a platform-variable set of 30-50 extension strings and getShaderPrecisionFormat() reveals vertex and fragment shader precision characteristics [22][23].

Chrome has not deprecated WEBGL_debug_renderer_info - Firefox has [24]. Detection requires wrapping WebGLRenderingContext.prototype.getParameter, .getExtension and the WebGL2 equivalents.

WebGPU Fingerprinting

This is the newer threat. navigator.gpu.requestAdapter() exposes adapter.info with vendor, architecture, device and description properties. The adapter.limits object contains over 30 hardware capability values though Chrome reports tiered values rather than exact limits to reduce entropy [25]. A 2025 ACM WiSec paper demonstrated that GPU scheduling behaviour of compute shaders can re-identify devices with 70% accuracy from a pool of 500 [26]. WebGPU shipped in Chrome 113 and is now available across all major browsers [27].

AudioContext Fingerprinting

The Web Audio API's signal processing pipeline is being exploited to identify your device. The standard technique creates an OfflineAudioContext(1, 5000, 44100), connects an OscillatorNode through a DynamicsCompressorNode to the destination, calls startRendering() then hashes the rendered buffer via getChannelData(0) [28][29]. Different browser engines use different FFT implementations and SIMD optimisations producing approximately 5.4 bits of entropy. FingerprintJS specifically reads sample number 3396 from the buffer, identified as having the largest cross-browser variation [30].

Additional signals include AudioContext.sampleRate, baseLatency, outputLatency and destination.maxChannelCount [31][32]. Chrome applies no noise injection to audio output - this works fully.

Font Enumeration

Three approaches exist. The classic measureText() technique compares widths of a test string rendered with a target font versus a baseline fallback [33]. document.fonts.check("12px FontName") provides a direct oracle [34]. And the Font Access API (window.queryLocalFonts()) directly enumerates all installed fonts but requires a permission prompt [35][36]. CSS-only font detection uses @font-face with src: local(FontName), url('/tracking-endpoint') - if the local font exists the URL is never fetched and the server infers installed fonts from missing requests [37]. Font lists provide 6.9 to 13.9 bits of entropy.

Navigator and Screen Properties

The navigator object exposes numerous properties that collectively form a medium to high entropy fingerprint. navigator.hardwareConcurrency returns the logical CPU core count with no mitigation. navigator.deviceMemory returns bucketed RAM. navigator.languages reveals the ordered array of preferred locales - the permutation of multiple language preferences creates significant entropy [38].

navigator.plugins now returns a hardcoded list of 5 PDF viewer strings since around Chrome 90 - effectively neutralised. navigator.userAgent has been reduced and frozen since Chrome 107 [39]. But navigator.userAgentData.getHighEntropyValues() provides the replacement pathway, returning architecture, bitness, full version list, model and platform version via a Promise [40][41].

Screen properties provide medium entropy through the combination of dimensions, colour depth and window.devicePixelRatio. The screen.isExtended property exposes multi-monitor setups without a permission prompt [42].

WebRTC IP Leaks

RTCPeerConnection discovers IP addresses during ICE candidate gathering. The classic pattern creates a peer connection with a STUN server, calls createOffer() and setLocalDescription(), then parses IP addresses from onicecandidate events. Chrome has obfuscated local and private IPs via mDNS since Chrome 76 but public IP exposure via STUN remains unsolved [43][44]. Extension detection requires wrapping the RTCPeerConnection constructor in a main-world content script - chrome.webRequest cannot intercept UDP STUN packets.

TLS Fingerprinting

This is the one that gets away from us. JA3 and JA4 fingerprinting operates entirely at the network layer [45][46]. Chrome's BoringSSL has randomised TLS extension ordering since Chrome 108 rendering traditional JA3 hashes unstable. JA4 addresses this by sorting cipher suites and extensions before hashing. Extensions cannot observe the raw TLS ClientHello. This is the critical gap - passive network-layer fingerprinting is fundamentally invisible to browser extensions.

Emoji Rendering Fingerprinting

Each OS uses a different emoji font - Windows has Segoe UI Emoji, macOS has Apple Color Emoji, Android has Noto Color Emoji. Rendering emoji to a canvas and hashing the pixels produces OS-specific output. Research testing 1,791 emoji found 114 with rendering differences across 11 browsers [47]. The DOMRect measurement technique provides up to 16 decimal places of width and height precision without even using canvas [48].

Speech Synthesis Fingerprinting

speechSynthesis.getVoices() returns an array of SpeechSynthesisVoice objects whose name, lang, localService and voiceURI properties vary dramatically by OS and installed voice packs. Chrome adds Google cloud voices alongside system voices creating high entropy. No permission or user gesture is required. Chrome has no mitigation.

Keyboard Layout Fingerprinting

navigator.keyboard.getLayoutMap() enumerates the physical-to-character key mapping, instantly distinguishing QWERTY, AZERTY, QWERTZ, Dvorak and Colemak layouts [49][50]. Both Firefox and Safari refuse to implement this API due to fingerprinting concerns [51]. Chrome ships it with no restrictions.

Motion and Sensor Fingerprinting

The Generic Sensor API exposes manufacturing-specific calibration data through Accelerometer and Gyroscope that can uniquely identify physical devices. The W3C spec explicitly documents this threat. Chrome mitigates by rounding sensor readings to 0.1 m/s squared for accelerometers [52]. A more subtle leak - Sensor.timestamp was found to expose device boot time rather than page-relative time, creating a persistent identifier.

Bluetooth, USB and HID Enumeration

These APIs follow the same pattern - initial device pairing requires a user gesture plus a chooser dialog but subsequent calls to getDevices() silently enumerate previously paired devices. navigator.usb.getDevices() exposes vendorId, productId and critically serialNumber [53][54].

Math Constant Fingerprinting

ECMAScript does not precisely specify transcendental function implementations. Math.tan(-1e308) produces the biggest cross-browser variation [55][56]. However V8 has used fdlibm since around 2016 producing identical results across all Chrome platforms - this makes math fingerprinting useful primarily for distinguishing browser engines rather than OS within Chrome [57].

CSS Media Queries Fingerprinting

This is the one that keeps me up at night because it works without JavaScript. Media queries collectively provide over 10 bits of entropy through prefers-color-scheme, prefers-reduced-motion, colour-gamut, dynamic-range, forced-colours, pointer and hover [58]. An NDSS 2025 paper demonstrated that 702 of 922 browser releases are uniquely identifiable via @supports queries alone [59]. CSS fingerprinting triggers loading unique background-image URLs whose server-side logs reveal device characteristics - making content-script-based detection largely ineffective. The only extension-based defence is network-level blocking of the tracking URLs that CSS fingerprinting triggers.

Performance API Timing Attacks

performance.now() provides 100 microsecond precision in non-isolated contexts and 5 microseconds with cross-origin isolation [60][61]. This enables cache probing, extension detection and XS-Leaks. SharedArrayBuffer can construct nanosecond timers but requires COOP and COEP headers since Chrome 92 [62].

Installed Extension Detection

Web Accessible Resources probing fetches chrome-extension://[known-id]/[resource] - BrowserLeaks tests against the top 5,000 extensions [63]. Timing-based detection measures fetch latency differences between fake and real extension resources [64][65]. A 2021 USENIX Security paper found 17,712 extensions inject CSS files detectable via decoy trigger DOM elements [66].

Remaining Vectors

Several additional vectors round out the fingerprinting surface. The Battery API combines level, charging state and timing for thousands of unique combinations though Chrome on desktop now returns hardcoded defaults [67][68]. The Network Information API exposes effective connection type, downlink and round-trip time [69][70]. The Compute Pressure API reports CPU utilisation in four states [71][72]. WebAssembly feature detection via WebAssembly.validate() creates a multi-bit feature bitmap distinguishing browser versions [73]. The Gamepad API exposes device identifiers though Chrome requires a button press first. Web MIDI now requires a permission prompt since Chrome 124 [74].

And all of this - every single one of these techniques - works in Chrome right now with essentially no built-in protection.


Part 2: Storage and Tracking - The Mechanisms That Follow You Everywhere

If fingerprinting is about identifying your device then storage and tracking mechanisms are about following you across the web and through time. There are at least 23 distinct client-side storage and tracking vectors exploitable in Chrome and an MV3 extension with debugger access can detect every single one of them [75].

The Cookie Landscape

With Google's abandonment of third-party cookie deprecation in July 2024 and the October 2025 retirement of Privacy Sandbox replacement APIs, third-party cookies remain fully operational in Chrome with no removal timeline [76][77][78]. Let me be clear about what this means - after six years of promising to remove third-party cookies, after building an entire Privacy Sandbox ecosystem supposedly designed to replace them, Google simply gave up and left them in place.

First-party cookies remain the most reliable tracking vector. Trackers embed first-party JavaScript that persists identifiers for up to two years. Detection uses chrome.cookies.getAll({domain: targetDomain}) and chrome.cookies.onChanged for real-time monitoring [79][80]. The CDP Storage.getCookies command provides an alternative path.

Third-party cookies are set by domains other than the top-level page, typically via embedded iframes, tracking pixels or script-initiated requests. A tracker at ads.example.com embedded across thousands of sites maintains a single shared cookie jar enabling full cross-site user identification. Detection requires monitoring Set-Cookie response headers on cross-origin requests via chrome.webRequest.onHeadersReceived with the extraHeaders option which is required in MV3 [81][82].

SameSite behaviour governs cross-site cookie transmission. SameSite=Lax is Chrome's default since Chrome 80 restricting cookies to same-site requests plus top-level navigations. SameSite=None; Secure explicitly enables cross-site transmission which is what trackers require [83][84]. The chrome.cookies API exposes the sameSite property on every cookie object enabling detection of tracking-permissive cookies.

CHIPS - Cookies Having Independent Partitioned State - shipped in Chrome 114 and remains one of the surviving Privacy Sandbox features. The Partitioned attribute opts a cookie into double-keyed storage using the combination of top-level site and cookie domain [85][86]. A partitioned cookie set by tracker.com embedded in site-a.com is invisible when tracker.com is embedded in site-b.com. Chrome limits 180 cookies per partition not exceeding 10 KB per embedded site [87]. The chrome.cookies API supports a partitionKey parameter for full partition-aware enumeration [88].

Bounce Tracking and Redirect Chains

Bounce tracking works by inserting redirect hops through tracker domains during navigation. When you click a link the browser navigates through tracker.com/redirect?uid=X&dest=target.com, allowing the tracker to read and set first-party cookies during the momentary visit then redirects to the destination [89]. Chrome launched bounce tracking mitigations that monitor redirect chains, flag stateful bounces and delete all storage for bounce domains without user interaction in the past 45 days [90][91]. Detection uses chrome.webNavigation.onBeforeNavigate and onCommitted to track redirect chains, flagging navigations where transition qualifiers include server or client redirects through known tracker domains.

Link Decoration

This one is insidious in its simplicity. Tracking identifiers are appended as URL parameters to outbound links - fbclid from Facebook, gclid and dclid from Google Ads, msclkid from Microsoft, srsltid from Google Shopping and _ga from Google Analytics [92][93]. These enable cross-site identity bridging by passing a user identifier from the source site to the destination in the URL where first-party JavaScript reads it and stores it as a cookie. Detection monitors URLs in webRequest and webNavigation listeners, parsing query parameters against a known tracking parameter list.

CNAME Cloaking

This is perhaps the most devious technique in the entire tracking arsenal. A tracker configures a CNAME DNS record so that tracking.publisher.com resolves to tracker-server.thirdparty.com. This makes tracking requests appear first-party, bypassing third-party cookie blocks, ad blockers and privacy extensions [94][95][96].

Research by Dao et al. found 1,762 websites using CNAME cloaking across 56 tracking providers with Adobe at 61%, followed by Eulerian, Act-on and Criteo [97][98]. A critical security concern - cookies scoped to *.publisher.com including authentication cookies are automatically sent to the cloaked tracker.

Chrome notably does not expose DNS APIs to extensions - unlike Firefox where uBlock Origin performs DNS lookups [99]. Detection in Chrome requires alternative approaches - compare request IP addresses against known tracker IPs using the CDP Network.responseReceived event which includes remoteIPAddress, use maintained CNAME blocklists from AdGuard or EasyPrivacy, or employ machine learning classification of subdomain request patterns.

Web Storage APIs

localStorage persists indefinitely at roughly 5 MB per origin, survives browser restarts and is shared across all tabs of the same origin. It serves as the backbone of evercookie and supercookie respawning - trackers store a UUID that survives cookie clearing since users rarely clear localStorage [100]. The storage event fires in all other same-origin tabs when setItem is called enabling cross-tab tracking coordination [101][102].

Chrome partitions localStorage in third-party iframe contexts since Chrome 115 but first-party localStorage remains unpartitioned [103][104]. Detection via CDP uses DOMStorage.enable followed by DOMStorage.getDOMStorageItems. Real-time monitoring captures DOMStorage.domStorageItemAdded and domStorageItemUpdated events [105]. Page-context hooks via main-world content scripts monkey-patch Storage.prototype.setItem.

IndexedDB offers essentially unlimited storage with full NoSQL capabilities. Princeton researchers first documented commercial IndexedDB supercookies on weibo.com in 2014 [106]. Chrome partitions IndexedDB in third-party contexts since Chrome 115 [107]. CDP detection uses IndexedDB.requestDatabaseNames to list databases and IndexedDB.requestData to read object store contents [108][109].

Cache API and CacheStorage enables programmatic caching of responses containing tracking identifiers. A tracker calls caches.open('tracker-cache') then cache.put(url, response) to store a response containing a user ID that persists across sessions. CDP detection uses CacheStorage.requestCacheNames and CacheStorage.requestEntries [110][111].

Web SQL Database has been completely removed from Chrome as of Chrome 124 in April 2024. Any detection of window.openDatabase() calls indicates legacy dead code [112].

HTTP Header Tracking

ETag and If-None-Match tracking exploits HTTP cache validation headers to create stateless supercookies. On first request the server sends ETag: "USER-7a3b9f2c" - a unique per-user identifier disguised as a cache validator. On subsequent requests the browser automatically sends If-None-Match: "USER-7a3b9f2c" revealing the user's identity without any JavaScript or cookies [113][114]. The KISSmetrics scandal of 2011 demonstrated this in production resulting in a class-action lawsuit.

Chrome's HTTP cache partitioning shipped in Chrome 86 using a triple key of top-level site, frame site and resource URL [115]. This blocks cross-site ETag tracking but first-party ETag tracking remains fully functional. Detection monitors ETag response headers via chrome.webRequest.onHeadersReceived and If-None-Match request headers via onBeforeSendHeaders, both requiring the extraHeaders option.

HSTS supercookies encode user identifiers in HSTS pin states across multiple subdomains. A tracker controlling 32 subdomains can store a 32-bit identifier - each subdomain where HSTS is set represents a 1-bit [116][117]. Chrome mitigates this by clearing HSTS state when cookies are cleared and using separate HSTS stores for incognito sessions [118].

Favicon cache tracking exploits the browser's separate favicon database. Unlike HTTP cache, the favicon cache historically was not cleared when users cleared browsing data and persisted across incognito sessions [119][120]. A tracker encodes bits by caching and not-caching favicons across sub-paths, then on return visits observes which favicon requests arrive versus which do not [121]. Chrome 115's storage partitioning addresses third-party scenarios but the favicon cache remains architecturally separate from standard cache clearing.

Alt-Svc header persistence enables tracking by assigning per-user alternative service endpoints. A server sends Alt-Svc: h2="user123.tracker.com:443"; ma=2592000 and for 30 days the browser automatically connects to that user-specific endpoint identifying the returning user [122].

HTTP 103 Early Hints allow servers to send preliminary Link headers for preloading before the final response. Potential tracking vectors include per-user preconnect targets. Chrome restricts Early Hints to top-level frame HTTP/2+ requests only - low practical risk with no documented production use for tracking [123][124].

Workers and Cross-Tab Channels

Service Workers provide the most persistent tracking vector after cookies. Once registered, a Service Worker survives tab closure and browser restarts. It intercepts all in-scope network requests via the fetch event enabling identifier injection. Google Tag Manager officially adopted Service Workers for tracking in March 2025 [125][126]. Background Sync wakes the worker when connectivity returns even with no open tabs. Chrome 115 partitions third-party Service Workers by top-level site. Detection uses CDP Target.getTargets() to list all service worker targets and main-world hooks intercepting navigator.serviceWorker.register().

SharedWorkers persist as a single instance per origin shared across all tabs maintaining in-memory tracking state without touching any storage API [127]. BroadcastChannel enables same-origin cross-tab message broadcasting which trackers use to synchronise identifiers instantly across tabs [128]. Both are partitioned in third-party contexts since Chrome 115.

window.name historically persisted across navigations including cross-origin ones but Chrome now clears it on cross-site navigations. This vector is largely defunct [129].

Referrer Leaks

Chrome defaults to strict-origin-when-cross-origin since Chrome 85 sending only the origin and not the full URL cross-origin [130]. However sites can set weaker policies. A critical vulnerability - CVE-2025-4664 - allowed attackers to set referrer-policy: unsafe-url via Link headers on sub-resource requests, leaking full URLs with tokens. It was actively exploited before being patched in Chrome 136 [131][132].

Privacy Sandbox APIs

The Shared Storage API provides cross-site unpartitioned key-value storage with restricted output gates. It was in general availability but is scheduled for phaseout following the October 2025 Privacy Sandbox retirement [133][134].

The Storage Access API allows embedded cross-site iframes to request access to unpartitioned cookies via document.requestStorageAccess(). Chrome 119+ supports it with safeguards including user gesture requirements and prior top-level visit within 30 days [135][136][137].

The Topics API classified visited sites into roughly 469 interest categories using on-device machine learning. It has been retired as part of the October 2025 shutdown [138][139][140].


The Detection Architecture

A fully equipped forensic detection extension operates across four layers simultaneously. Let me be explicit about what you need.

Layer 1 - chrome.debugger CDP provides the deepest inspection with access to DOMStorage, IndexedDB, CacheStorage, Network, Storage, Target, ServiceWorker, Runtime and Security domains [141][142][143]. Key commands include DOMStorage.getDOMStorageItems, IndexedDB.requestDatabaseNames, CacheStorage.requestCacheNames, Network.enable with all request and response events, and Target.getTargets for worker enumeration.

Layer 2 - chrome.webRequest monitors all HTTP traffic observationally in MV3. The onBeforeSendHeaders event reveals outgoing tracking headers. The onHeadersReceived event captures incoming tracking headers. The extraHeaders option is required in MV3 to access Set-Cookie and other restricted headers [144][145][146].

Layer 3 - chrome.cookies API provides full cookie CRUD. It can read httpOnly cookies unlike document.cookie, access cookies across partitionKey values, inspect sameSite attributes and enumerate cookie stores for regular and incognito profiles [147].

Layer 4 - Main-world content scripts share the page's JavaScript execution environment enabling monkey-patching of all relevant APIs [148][149]. Main-world scripts cannot access chrome APIs directly - they communicate to isolated-world content scripts via window.postMessage.

The required manifest permissions are cookies, webRequest, webNavigation, debugger, tabs, scripting, storage, privacy plus host_permissions: ["<all_urls>"] [150].


Comprehensive Detection Reference

Vector Chrome Status Best Detection Method Key APIs to Intercept
Canvas Works, no mitigation Main-world Proxy toDataURL, toBlob, getImageData
WebGL Works, not deprecated Main-world Proxy getParameter, getExtension
WebGPU Works, tiered limits Main-world Proxy requestAdapter, adapter.info
Audio Works, no mitigation Main-world Proxy startRendering, getChannelData
Speech Works, no mitigation Main-world wrap speechSynthesis.getVoices
Fonts (measureText) Works, no mitigation Main-world wrap measureText, fonts.check
Fonts (Font Access) Permission-gated Main-world wrap queryLocalFonts
Navigator props Mostly works, UA frozen Main-world defineProperty Navigator.prototype getters
Screen props Works, no mitigation Main-world defineProperty Screen.prototype getters
Client Hints (JS) Works, Chromium-only Main-world wrap getHighEntropyValues
Client Hints (HTTP) Works webRequest headers Sec-CH-UA headers
WebRTC Local IPs via mDNS Main-world constructor Proxy RTCPeerConnection
TLS (JA3/JA4) Extension-randomised Cannot detect client-side N/A
Extension detection Works, WAR probeable declarativeNetRequest Block probing requests
Emoji rendering Works, no mitigation Same as canvas fillText, getBoundingClientRect
CSS media queries Works, no mitigation Main-world wrap and network matchMedia, CSS URL loads
Performance timing 100us precision Main-world wrap performance.now
WebAssembly Works, no mitigation Main-world wrap WebAssembly.validate
Keyboard layout Works, Chromium-only Main-world wrap getLayoutMap
Battery Desktop neutered Main-world wrap navigator.getBattery
Math constants Cross-engine only Main-world wrap Math.tan, Math.sin
Sensors Works, readings rounded Main-world Proxy Accelerometer, Gyroscope
First-party cookies Fully functional chrome.cookies API getAll, onChanged
Third-party cookies Enabled by default webRequest headers Set-Cookie monitoring
CHIPS Double-keyed chrome.cookies partitionKey partitionKey enumeration
Bounce tracking Mitigated for 3P blockers webNavigation Redirect chain tracking
Link decoration Works, no mitigation webRequest URL parsing Query parameter matching
CNAME cloaking No Chrome protection CDP Network.responseReceived remoteIPAddress comparison
localStorage Works (1P unpartitioned) CDP DOMStorage setItem, getItem
IndexedDB Works (1P unpartitioned) CDP IndexedDB requestDatabaseNames
Cache API Works (1P unpartitioned) CDP CacheStorage requestCacheNames
ETag tracking Works (1P) webRequest headers ETag, If-None-Match
HSTS supercookies Cleared with cookies webRequest headers Strict-Transport-Security
Favicon cache Partially separate CDP Network events Redirect chain patterns
Service Workers Fully functional CDP Target.getTargets SW registration
Shared Storage Being retired Main-world wrap sharedStorage.set
Storage Access API Supported, safeguarded Main-world wrap requestStorageAccess

Conclusion

Three things stand out from this analysis.

First - Chrome provides almost no native anti-fingerprinting defences. Unlike Brave, Firefox or Tor Browser, Chrome ships canvas, audio, WebGL, fonts and speech synthesis APIs completely unprotected. Google spent six years building a Privacy Sandbox, abandoned it and left us with nothing.

Second - first-party tracking remains entirely unmitigated. Every storage API, every cache mechanism and every HTTP header trick works fully when executed in the first-party context. CNAME cloaking makes this particularly dangerous by disguising third-party trackers as first-party subdomains and Chrome is the only major browser that neither blocks CNAME cloaking natively nor exposes DNS APIs to extensions for detection.

Third - despite all of this, the MV3 extension architecture is surprisingly capable for forensic detection. The main-world content script injection combined with CDP via the debugger API provides near-complete API interception coverage. The primary gap is passive network-layer fingerprinting which is fundamentally invisible to browser extensions.

I have spent my life fighting for the right to privacy because I have seen what happens when that right is taken away. The technologies described in this document are not theoretical - they are deployed at scale against billions of people every single day. Understanding them is the first step. Building the tools to detect and expose them is the next.

And for those who would say there is nothing to be done about it - I refer you to a billion dollar spyware company that no longer exists because a handful of ordinary people decided to do something about it.


References

[1] "Your Browser Is Unique Among Millions: How Fingerprinting Works," DEV Community. https://dev.to/michael_lip_52d5151c3e364/your-browser-is-unique-among-millions-how-fingerprinting-works-84a

[2] "Browser Fingerprinting Guide 2026," Proxies. https://www.proxies.sx/use-cases/privacy/fingerprinting

[3] "Block (most) canvas and webgl fingerprinting by default," Brave Browser, GitHub. https://github.com/brave/browser-laptop/pull/1354/files

[4] "Browser Fingerprint Detection and Anti-Tracking," arXiv. https://arxiv.org/html/2502.14326v1

[5] "Update on Plans for Privacy Sandbox Technologies," Google Privacy Sandbox. https://privacysandbox.google.com/blog/update-on-plans-for-privacy-sandbox-technologies

[6] "Google Privacy Sandbox officially shuts down," Usercentrics. https://usercentrics.com/knowledge-hub/what-is-google-privacy-sandbox/

[7] "Chrome kills most Privacy Sandbox technologies after adoption fails," PPC Land. https://ppc.land/chrome-kills-most-privacy-sandbox-technologies-after-adoption-fails/

[8] "How to Inject a Global with Web Extensions in Manifest V3," David Walsh. https://davidwalsh.name/inject-global-mv3

[9] "Content scripts," Chrome for Developers. https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts

[10] "chrome.debugger API," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/api/debugger

[11] "What Is Chrome DevTools Protocol (CDP)?," Decodo. https://decodo.com/glossary/cdp

[12] "Tutorial: Chrome Devtools Protocol (CDP)," Sitespeed. https://www.sitespeed.io/documentation/sitespeed.io/scripting/tutorial-11-Chrome-Devtools-Protocol.html

[13] "webRequest docs and MV3 deprecation," Chromium Extensions, Google Groups. https://groups.google.com/a/chromium.org/g/chromium-extensions/c/MPCKIx2Rgv8

[14] "chrome.declarativeNetRequest API," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest

[15] "Canvas fingerprinting," Wikipedia. https://en.wikipedia.org/wiki/Canvas_fingerprinting

[16] "What Is Canvas Fingerprinting?," Conbersa. https://www.conbersa.ai/learn/what-is-canvas-fingerprint

[17] "fingerprintjs/src/sources/canvas.ts," FingerprintJS, GitHub. https://github.com/fingerprintjs/fingerprintjs/blob/master/src/sources/canvas.ts

[18] "DRAWNAPART: A Device Identification Technique based on Remote GPU Fingerprinting," arXiv. https://arxiv.org/abs/2201.09956

[19] "WEBGL_debug_renderer_info extension," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_debug_renderer_info

[20] "What is WebGL Fingerprinting and How to Bypass It in 2026," Roundproxies. https://roundproxies.com/blog/webgl-fingerprinting/

[21] "Browser Fingerprinting," Pydoll. https://pydoll.tech/docs/deep-dive/fingerprinting/browser-fingerprinting/

[22] "WebGLRenderingContext: getShaderPrecisionFormat() method," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getShaderPrecisionFormat

[23] "What is WebGL Fingerprinting? How It Works & Tips," Medium. https://medium.com/@datajournal/webgl-fingerprinting-60893a9ca382

[24] "No note that WEBGL_debug_renderer_info is deprecated on Firefox," MDN Content, GitHub. https://github.com/mdn/content/issues/12689

[25] "WebGPU Features Database," Scrapfly. https://scrapfly.io/web-scraping-tools/gpu-fingerprint/webgpu

[26] "Unveiling Privacy Risks in WebGPU through Hardware-based Device Fingerprinting," ACM WiSec. https://dl.acm.org/doi/10.1145/3734477.3734700

[27] "WebGPU Hits Critical Mass: All Major Browsers Now Ship It," WebGPU Community. https://www.webgpu.com/news/webgpu-hits-critical-mass-all-major-browsers/

[28] "AudioContext Fingerprinting," Darkwave Technologies. https://www.darkwavetech.com/projects/device-fingerprinting/audiocontext-fingerprinting

[29] "How the Web Audio API is used for browser fingerprinting," DEV Community. https://dev.to/savannahjs/how-the-web-audio-api-is-used-for-browser-fingerprinting-4oim

[30] "Audio Fingerprinting: What It Is + How It Works with Web API," Fingerprint. https://fingerprint.com/blog/audio-fingerprinting/

[31] "AudioContext: outputLatency property," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/outputLatency

[32] "How We Bypassed Safari 17's Advanced Audio Fingerprinting Protection," Fingerprint. https://fingerprint.com/blog/bypassing-safari-17-audio-fingerprinting-protection/

[33] "Browser fingerprints in a nutshell," Naif Mehanna. https://naifmehanna.com/2018-09-16-browser-fingerprints-in-a-nutshell/

[34] "FontFaceSet.check," W3cubDocs. https://docs.w3cub.com/dom/fontfaceset/check

[35] "Use advanced typography with local fonts," Chrome for Developers. https://developer.chrome.com/docs/capabilities/web-apis/local-fonts

[36] "WICG/local-font-access," GitHub. https://github.com/WICG/local-font-access

[37] "Font Leak Tester," Trust My IP. https://trustmyip.com/font-leak-tester

[38] "JavaScript Tricks: Device Fingerprint," Medium. https://medium.com/@6465660/javascript-tricks-device-fingerprint-f0680b284337

[39] "Browser Fingerprinting: Complete Guide to Detection & Protection," Multilogin. https://multilogin.com/blog/browser-fingerprinting-the-surveillance-you-can-t-stop/

[40] "Preparing for Chrome User-Agent Client Hints," MGID. https://www.mgid.com/blog/preparing-for-chrome-user-agent-client-hints-an-update-for-mgid-clients

[41] "User-Agent Client Hints API," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/User-Agent_Client_Hints_API

[42] "window-management/EXPLAINER.md," W3C, GitHub. https://github.com/w3c/window-management/blob/main/EXPLAINER.md

[43] "PSA: Private IP addresses exposed by WebRTC changing to mDNS hostnames," Google Groups. https://groups.google.com/g/discuss-webrtc/c/6stQXi72BEU

[44] "Prflxion - a WebRTC ip leak," Medium. https://medium.com/@peer5/prflxion-a-webrtc-ip-leak-60b3d6b82f49

[45] "Google Chrome TLS extension permutation," GitHub. https://github.com/net4people/bbs/issues/220

[46] "JA3 Fingerprints Fade as Browsers Embrace TLS Extension Randomization," Stamus Networks. https://www.stamus-networks.com/blog/ja3-fingerprints-fade-browsers-embrace-tls-extension-randomization

[47] "Emoji rendering differences enough to identify devices and browsers," PortSwigger. https://portswigger.net/daily-swig/emoji-rendering-differences-enough-to-identify-devices-and-browsers

[48] "Fingerprinting Emoji," TU Munich Privacy Check. https://privacycheck.sec.lrz.de/active/fp_e/fp_emoji.html

[49] "Keyboard API," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/Keyboard_API

[50] "Disable Keyboard API fingerprinting," Brave Browser, GitHub. https://github.com/brave/brave-browser/issues/3964

[51] "Keyboard Map specification," WICG. https://wicg.github.io/keyboard-map/

[52] "Sensors for the web," Chrome Developers. https://chrome.jscn.org/articles/generic-sensor/

[53] "Web Bluetooth specification," WebBluetoothCG. https://webbluetoothcg.github.io/web-bluetooth/

[54] "Bluetooth: getDevices() method," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/Bluetooth/getDevices

[55] "Math keeps changing," macwright.com. https://macwright.com/2020/02/14/math-keeps-changing

[56] "Math Routine Fingerprinting," Darkwave Technologies. https://www.darkwavetech.com/projects/device-fingerprinting/math-routine-fingerprinting

[57] "Intent to Implement: Use fdlibm for Math.cos, Math.sin, and Math.tan," Mozilla dev-platform, Google Groups. https://groups.google.com/a/mozilla.org/g/dev-platform/c/0dxAO-JsoXI/m/eEhjM9VsAgAJ

[58] "What Browser Fingerprinting Techniques Exist," Factually. https://factually.co/fact-checks/technology/browser-fingerprinting-techniques-and-how-to-reduce-your-fingerprint-b661d2

[59] "Cascading Spy Sheets," NDSS 2025 (referenced in browser fingerprinting research). https://multilogin.com/blog/browser-fingerprint-chrome/

[60] "Intent to Ship: Align performance API timer resolution to cross-origin isolated capability," Chromium Blink-dev, Google Groups. https://groups.google.com/a/chromium.org/g/blink-dev/c/k6M3HJiqmkE

[61] "Performance: now() method," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

[62] "On High-Precision JavaScript Timers," Incolumitas. https://incolumitas.com/2021/12/18/on-high-precision-javascript-timers/

[63] "Chrome Extension Detection," BrowserLeaks. https://browserleaks.com/chrome

[64] "Extension-detector: Browser Extension Fingerprinting Tool," DataDome. https://datadome.co/anti-detect-tools/extension-detector/

[65] "Unnecessarily Identifiable: Quantifying the fingerprintability of browser extensions due to bloat," ACM. https://dl.acm.org/doi/fullHtml/10.1145/3308558.3313458

[66] "Fingerprinting in Style: Detecting Browser Extensions via Injected Style Sheets," USENIX Security 2021. https://www.usenix.org/system/files/sec21fall-laperdrix.pdf

[67] "Battery Status Detector," Scrapfly. https://scrapfly.io/web-scraping-tools/battery-status

[68] "Battery Status API," W3C. https://w3c.github.io/battery/

[69] "NetworkInformation: effectiveType property," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType

[70] "Network Information API," WICG. https://wicg.github.io/netinfo/

[71] "Compute Pressure API: A Deep Dive," Catch Metrics. https://www.catchmetrics.io/blog/compute-pressure-api-a-deep-dive-into-adaptive-web-performance

[72] "w3c/compute-pressure," GitHub. https://github.com/w3c/compute-pressure

[73] "Browser Fingerprinting Using WebAssembly," arXiv. https://arxiv.org/pdf/2506.00719

[74] "GoogleChromeLabs/wasm-feature-detect," GitHub. https://github.com/GoogleChromeLabs/wasm-feature-detect/tree/main

[75] "Storage Partitioning," Google Privacy Sandbox. https://privacysandbox.google.com/cookies/storage-partitioning

[76] "How Third-Party Cookies Deprecation Affects Programmatic Ecosystem," Adtelligent. https://adtelligent.com/blog/ad-tech-insights/how-third-party-cookies-elimination-will-affect-programmatic-ecosystem/

[77] "Google Cookie Deprecation U-Turn," CookieYes. https://www.cookieyes.com/blog/google-cookie-deprecation/

[78] "Update on Plans for Privacy Sandbox Technologies," Google. https://privacysandbox.google.com/blog/update-on-plans-for-privacy-sandbox-technologies

[79] "chrome.cookies API," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/api/cookies

[80] "Understanding Chrome Extensions Cookies," Medium. https://m2kdevelopments.medium.com/16-understanding-chrome-extensions-cookies-4c4557a812b3

[81] "Reliably Detecting Third-Party Cookie Blocking In 2025," Smashing Magazine. https://www.smashingmagazine.com/2025/05/reliably-detecting-third-party-cookie-blocking-2025/

[82] "SameSite Cookie Attribute explained," Cookie-Script. https://cookie-script.com/documentation/samesite-cookie-attribute-explained

[83] "SameSite Cookie Attribute: Lax, Strict, None Guide," Kukie. https://kukie.io/blog/samesite-cookie-attribute-explained

[84] "SameSite Cookie Attribute explained," Cookie-Script. https://cookie-script.com/documentation/samesite-cookie-attribute-explained

[85] "Cookies Having Independent Partitioned State (CHIPS)," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies

[86] "Cookies Having Independent Partitioned State (CHIPS)," Google Privacy Sandbox. https://privacysandbox.google.com/cookies/chips

[87] "CHIPS specification," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies

[88] "chrome.cookies API," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/api/cookies

[89] "Bounce tracking mitigations," Google Privacy Sandbox. https://privacysandbox.google.com/protections/bounce-tracking-mitigations

[90] "Help test bounce tracking mitigations," Chrome for Developers Blog. https://developer.chrome.com/blog/bounce-tracking-mitigations-dev-trial

[91] "Navigational-Tracking Mitigations," Privacy CG. https://privacycg.github.io/nav-tracking-mitigations/

[92] "Prevent tracking based on link decoration via query string or fragment," Brave Browser, GitHub. https://github.com/brave/brave-browser/issues/4239

[93] "How to Set Up Conditional Link Decoration for Cross-Domain Tracking," Optizent. https://www.optizent.com/blog/how-to-set-up-conditional-link-decoration-for-cross-domain-tracking/

[94] "CNAME Cloaking-Based Tracking on the Web," IEEE TNSM. https://ieeexplore.ieee.org/document/9403411/

[95] "Online Trackers Increasingly Switching to Invasive CNAME Cloaking Technique," The Hacker News. https://thehackernews.com/2021/02/online-trackers-increasingly-switching.html

[96] "How Browser Fingerprinting Works: a Full Breakdown," Octo Browser. https://blog.octobrowser.net/how-browser-fingerprinting-works

[97] "CNAME Cloaking-Based Tracking on the Web: Characterization, Detection, and Protection," Dao et al., IEEE TNSM 2021. http://www.fukuda-lab.org/publications/2021/DMF_tnsm2021.pdf

[98] "A machine learning approach for detecting CNAME cloaking-based tracking," IEEE Conference. https://ieeexplore.ieee.org/document/9322514/

[99] "CNAME Cloaking: Disguising Third Parties Through the DNS," Palo Alto Networks Unit 42. https://unit42.paloaltonetworks.com/cname-cloaking/

[100] "Evercookie," Wikipedia. https://en.wikipedia.org/wiki/Evercookie

[101] "Cross-tab communication using localStorage," Coderwall. https://coderwall.com/p/bmzw8g/cross-tab-communication-using-localstorage

[102] "LocalStorage, sessionStorage," JavaScript.info. https://javascript.info/localstorage

[103] "Storage Partitioning," Google Privacy Sandbox. https://privacysandbox.google.com/cookies/storage-partitioning

[104] "Storage Partitioning," Chrome for Developers. https://developer.chrome.com/docs/privacy-sandbox/storage-partitioning/

[105] "Chrome DevTools Protocol - DOMStorage domain." https://chromedevtools.github.io/devtools-protocol/tot/DOMStorage/

[106] "Exploiting IndexedDB API information leaks," referenced in MalwareTips Forums. https://malwaretips.com/threads/exploiting-indexeddb-api-information-leaks-in-safari-15.111978/

[107] "Storage Partitioning - IndexedDB," Chrome for Developers. https://developer.chrome.com/docs/privacy-sandbox/storage-partitioning/

[108] "Chrome DevTools Protocol - IndexedDB domain." https://chromedevtools.github.io/devtools-protocol/tot/IndexedDB/

[109] "Chrome DevTools Protocol - Storage domain." https://chromedevtools.github.io/devtools-protocol/tot/Storage/

[110] "Chrome DevTools Protocol - CacheStorage domain." https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage/

[111] "Participate in early testing for Storage Partitioning," Google Developers. https://developers.google.com/privacy-sandbox/blog/storage-partitioning-dev-trial

[112] "Evercookie - Web SQL removal," Wikipedia. https://en.wikipedia.org/wiki/Evercookie

[113] "ETag Fingerprinting," TU Munich Privacy Check. https://privacycheck.sec.lrz.de/passive/fp_etag/fp_etag.php

[114] "HTTP ETag," Wikipedia. https://en.wikipedia.org/wiki/HTTP_ETag

[115] "Gaining security and privacy by partitioning the cache," Chrome for Developers Blog. https://developer.chrome.com/blog/http-cache-partitioning

[116] "HSTS Supercookie," GitHub. https://github.com/ben174/hsts-cookie

[117] "Apple Blocks Sites From Abusing HSTS Security Standard to Track Users," The Hacker News. https://thehackernews.com/2018/03/hsts-supercookie-tracking.html

[118] "Revisiting HSTS supercookies," Browserprint, University of Adelaide. https://browserprint.services.adelaide.edu.au/blog/hstsSupercookie

[119] "Favicons may be used to track users," referenced in multiple sources. https://bitcoinwithmoney.com/technology/favicons-may-be-used-to-track-users/

[120] "supercookie: Browser fingerprinting via favicon," GitHub. https://github.com/jonasstrehle/supercookie

[121] "Browser favicons as user tracking Supercookies," CCL Solutions Group. https://www.cclsolutionsgroup.com/post/browser-favicons-as-user-tracking-supercookies

[122] "How Browser Fingerprinting Works: a Full Breakdown," Octo Browser. https://blog.octobrowser.net/how-browser-fingerprinting-works

[123] "Chromium Docs - 103 Early Hints." https://chromium.googlesource.com/chromium/src/+/master/docs/early-hints.md

[124] "103 Early Hints," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/103

[125] "Persistence Through Service Workers," TrustedSec. https://trustedsec.com/blog/persistence-through-service-workers-part-1-introduction-and-target-application-setup

[126] "Google tag now leverages service workers to enhance data collection," PPC Land. https://ppc.land/google-tag-now-leverages-service-workers-to-enhance-data-collection/

[127] "Best Way to Share a Single WebSocket Connection Across Multiple Tabs," CyberAngles. https://www.cyberangles.org/blog/best-proper-way-to-share-a-single-websocket-connection-across-multiple-tabs/

[128] "Storage Partitioning - BroadcastChannel," Google Privacy Sandbox. https://privacysandbox.google.com/cookies/storage-partitioning

[129] "Storage and cookies," Chrome for Developers. https://developer.chrome.com/docs/extensions/develop/concepts/storage-and-cookies

[130] "A new default Referrer-Policy for Chrome," Chrome for Developers Blog. https://developer.chrome.com/blog/referrer-policy-new-chrome-default

[131] "CISA: Recently fixed Chrome vulnerability exploited in the wild (CVE-2025-4664)," Help Net Security. https://www.helpnetsecurity.com/2025/05/16/cisa-recently-fixed-chrome-vulnerability-exploited-in-the-wild-cve-2025-4664/

[132] "New Chrome Vulnerability Enables Cross-Origin Data Leak via Loader Referrer Policy," The Hacker News. https://thehackernews.com/2025/05/new-chrome-vulnerability-enables-cross.html

[133] "Shared Storage API," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/Shared_Storage_API

[134] "Privacy Sandbox feature status," Google. https://privacysandbox.google.com/overview/status

[135] "Non-cookie storage access through the Storage Access API," Google Developers. https://developers.google.com/privacy-sandbox/blog/saa-non-cookie-storage

[136] "Storage Access API," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API

[137] "Topics API," Privacy Sandstorm. https://privacysandstorm.com/privacy-sandbox/topics/

[138] "Topics API," MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/Topics_API

[139] "Chrome kills most Privacy Sandbox technologies," PPC Land. https://ppc.land/chrome-kills-most-privacy-sandbox-technologies-after-adoption-fails/

[140] "Google Privacy Sandbox officially shuts down," Usercentrics. https://usercentrics.com/knowledge-hub/what-is-google-privacy-sandbox/

[141] "chrome.debugger API," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/api/debugger

[142] "Chrome DevTools Protocol from Extensions," Medium. https://medium.com/@dzianisv/vibe-engineering-chrome-devtools-protocol-from-extensions-you-dont-need-to-fork-chromium-72a9ffb68b6d

[143] "Chrome DevTools Protocol - DOMStorage domain." https://chromedevtools.github.io/devtools-protocol/tot/DOMStorage/

[144] "Replace blocking web request listeners," Chrome for Developers. https://developer.chrome.com/docs/extensions/develop/migrate/blocking-web-requests

[145] "webRequest docs and MV3," Chromium Extensions, Google Groups. https://groups.google.com/a/chromium.org/g/chromium-extensions/c/MPCKIx2Rgv8

[146] "Manifest - content scripts," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/manifest/content-scripts

[147] "chrome.cookies API," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/api/cookies

[148] "Content scripts," Chrome for Developers. https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts

[149] "Declare permissions," Chrome for Developers. https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions

[150] "Permissions list," Chrome for Developers. https://developer.chrome.com/docs/extensions/reference/permissions-list