A background script that persistently logs visited URLs to chrome.storage.local or an external server is, functionally, spyware — regardless of intent. GDPR Art. 5(1)(c) prohibits collecting data beyond what is necessary; Art. 5(1)(e) requires data not be retained longer than needed. Persistent browsing history in extension storage becomes a high-value target: a single compromise of the extension or its backend server exposes a complete record of the user's online behavior. The Chrome Web Store User Data Policy explicitly prohibits collecting user activity beyond declared core functionality, and violations result in immediate delisting.
High because persistent browsing history constitutes a detailed behavioral profile that, once collected, can be exfiltrated, subpoenaed, or sold — the harm is irreversible once the data exists.
Replace persistent storage writes inside tab listeners with in-memory state that clears on extension unload:
// GOOD — memory only, no persistent history log
let currentTabUrl = null;
chrome.tabs.onActivated.addListener(({ tabId }) => {
chrome.tabs.get(tabId, (tab) => {
currentTabUrl = tab.url; // Used in-session only, not persisted
});
});
If your feature genuinely requires storing activity (e.g., a user-controlled history tool), make it explicit: get consent first per pii-consent, encrypt the data per local-pii-encrypted, and document the retention period per retention-periods. Never write URL data to storage inside a tab event handler without those three controls in place.
ID: extension-data-privacy.data-collection.no-history-logging
Severity: high
What to look for: Examine the background script (service worker or persistent background page) for patterns that capture browsing history. Look for chrome.tabs.query, chrome.tabs.onActivated, chrome.webNavigation event listeners that store full URLs, page titles, or visit metadata to persistent storage.
Pass criteria: Enumerate all chrome.tabs and chrome.webNavigation listeners in the background script. Background script does not maintain a persistent log of browsing history. If it monitors tabs (for legitimate features), it only keeps in-memory state that is cleared on extension unload. 0% of tab/navigation events may be written to persistent storage without consent.
Fail criteria: Background script captures and persistently stores URLs, page titles, or tab metadata — e.g., all visited sites recorded to chrome.storage.local or sent to external server without explicit user notification. Should not pass when any chrome.storage write occurs inside a tab event listener.
Skip (N/A) when: Never — this is a critical privacy protection.
Detail on fail: Describe the history logging. Example: "Background script listens to chrome.tabs.onUpdated and logs all visited URLs to chrome.storage.local every 5 seconds with timestamps" or "Browser history exported and sent to analytics service on a schedule."
Remediation: If you need to track the current tab (legitimate), store it in memory only:
let currentTabUrl = null; // Memory-only, cleared on unload
chrome.tabs.onActivated.addListener((activeInfo) => {
chrome.tabs.get(activeInfo.tabId, (tab) => {
currentTabUrl = tab.url; // Use in memory, don't store persistently
});
});
If you must persist activity, encrypt it and get explicit consent.