Is TagHound - Analytics/GTM/Pixel Debugger safe?
We analyzed TagHound - Analytics/GTM/Pixel Debugger version 1.3.4's actual code and gave it a 55/100 trust score. A legitimate debugging tool has…
Bottom line
A legitimate debugging tool has unusually broad access and handles potentially sensitive analytics data, creating meaningful privacy and security concerns.
What it can access
It runs on every website and can read analytics events, page URLs, and matching request contents, which may contain personal or commercial data. [Q1][Q3][Q15][Q18]
Security weaknesses
Automatic all-site monitoring and storage of analytics contents could expose sensitive site data if the extension or its stored data is compromised. [Q1][Q2][Q3][Q8]
Signs of misuse
The extension sends usage telemetry, location details, and paid-license information to outside services, including suspected-sharing reports, beyond its core debugging display. [Q6][Q12][Q13][Q14]
Code findings
What access does this extension ask for, and does that access make sense for what it claims to do?
It requests webRequest, tabs, scripting, alarms, storage, unlimitedStorage, activeTab, and <all_urls> access. Isolated and MAIN-world page access run automatically on every page.
Declares all-site automatic scripts and the sensitive tab/network/storage permissions. — manifest.json:content_scripts, permissions, and host_permissions
Which websites can it run on, and can it read or change what appears on those pages?
It injects toast/controller iframes and styles into ordinary pages and runs a MAIN-world script that inspects GTM script tags and the page's dataLayer. It does not rewrite the site's business UI or arbitrary page content.
Creates extension iframes in the page and maintains their layout. — contentScript.bundle.js:iframe-manager.ts and toast.ts modules
Runs in the page world and inspects GTM script tags and dataLayer objects. — mainWorldContentScript.bundle.js:contentScript/component/gtm.ts
Can it see sensitive information you type, such as passwords, payment details, messages, or form entries?
It can read complete GTM dataLayer objects and matched analytics/ad request parameters, headers, and POST bodies. Those structures commonly include page URLs, product/order values, search terms, advertising identifiers, hashed contacts, or other site-supplied personal data, although the extension targets telemetry rather than arbitrary page fields.
Copies and flattens dataLayer additions, retaining event fields while recording page URL and host. — mainWorldContentScript.bundle.js:contentScript/component/gtm.ts
Captures raw POST bytes, request headers, URL, initiator/referrer, and timing for matched requests. — background.bundle.js:background/modules/web-request-handler.ts
Parses ecommerce, conversion, product, user, and validation fields for more than twenty analytics platforms. — background.bundle.js:background/components/pixel/modules/*
Can it access private browser data such as cookies, signed-in sessions, browsing history, bookmarks, or downloads?
It stores captured events/request details, recording state, active-tab timestamps, user options, excluded domains, display state, a random telemetry client ID, country/city, cloud announcements, and paid-license details through Redux-backed chrome.storage. unlimitedStorage removes the normal quota ceiling.
Requests storage and unlimitedStorage. — manifest.json:permissions
Persists the application, pixel, toast, option, client-ID, geo, cloud, and license slices in chrome.storage. — default-src_css_sass_app_scss-src_js_global_service_helper_ts-src_js_page_background_store_store_ts.bundle.js:background/store/store.ts and reducers
Can it access anything else on your device, such as files, location, camera, microphone, clipboard, or installed applications?
No evidence of this behavior was found in the reviewed package.
Declares none of the device, cookies, native messaging, file URL, or loopback capabilities. — manifest.json:permissions and host_permissions
Does it send information outside your browser? If so, what information is sent, where does it go, and why?
Its own feature and error events go to Google Analytics with a random persistent client ID plus country/city and event properties. It obtains country/city from ip-services.com, verifies license keys with Gumroad, and can report suspected shared licenses—including purchaser email, key, sale time, and usage counters—to Make.com webhooks.
Posts app events to Google Analytics Measurement Protocol with client ID and stored country/city. — background.bundle.js:global/utils/ga4.ts and message-handler.ts
Fetches country and city from ip-api.com and announcement JSON from GitHub. — background.bundle.js:global/service/index.ts
Sends license checks to Gumroad and suspected-sharing reports to two Make.com hooks. — background.bundle.js:global/service/modules/license/index.ts and daily-verify-taghound-plus-license.ts
Does it download or run code, settings, or instructions supplied by a remote server?
It downloads a public GitHub JSON file containing announcement messages and support/video links, country/city JSON from ip-services.com, and Gumroad license status. These remain data for fixed UI or licensing code; it does not download JavaScript or executable instructions.
Fetches GitHub message.json and ip-api country/city JSON. — background.bundle.js:global/service/index.ts
Sanitizes/formats message text and stores the returned announcement structure. — background.bundle.js:message-handler.ts
The install-page flag and URL are packaged locally rather than fetched remotely. — config.txt:complete file
Can it take actions without a clear user request, such as opening pages, redirecting searches, downloading files, or sending requests?
It automatically instruments every eligible page, polls dataLayer changes, observes matching analytics requests, maintains per-tab activity, and records events without a click for each event. The captured data supports its advertised debugging feature, and settings can exclude domains or put tabs to sleep.
Starts isolated and MAIN-world scripts on all URLs. — manifest.json:content_scripts
Polls and dispatches new dataLayer events when tracking is active. — mainWorldContentScript.bundle.js:contentScript/component/gtm.ts
Registers persistent webRequest listeners for all supported analytics URL filters. — background.bundle.js:background/modules/web-request-handler.ts
Can it change important browser settings, including your proxy, search engine, homepage, privacy settings, or other extensions?
No evidence of this behavior was found in the reviewed package.
Contains no browser-setting, search-provider, new-tab, proxy, management, or downloads override. — manifest.json:top-level fields and permissions
Is any important behavior difficult to inspect because the code is hidden, heavily obfuscated, dynamically generated, or supplied by third parties?
The package contains about 7.2 MB of minified one-line Webpack bundles and many large UI and parsing dependencies. Original application module paths and descriptive strings remain, making important behavior traceable, but complete independent review is expensive.
Lists multiple 0.5–1.2 MB application bundles and no separate source maps. — inventory.json:files
Combines network parsing, storage, licensing, telemetry, and dependencies into a 776 KB one-line bundle. — background.bundle.js:complete file
Does it use eval(), new Function(), or string-based timers to turn text into executable code?
No evidence of this behavior was found in the reviewed package.
Executes only the fixed literal string 'return this'. — background.bundle.js:Webpack runtime global fallback
Contain the same fixed packaged global-detection expression. — popup.bundle.js, panel.bundle.js, option.bundle.js, record.bundle.js:Webpack runtime global fallback
Does it track the websites, pages, searches, or links you visit?
It sees URLs on every eligible tab and continuously records the active tab's analytics/ad calls and GTM events, including page URL/hostname. The stored data is used locally for the debugger; its own GA telemetry records TagHound feature events, not the captured browsing event data.
Adds document.URL and location.hostname to each captured dataLayer event. — mainWorldContentScript.bundle.js:contentScript/component/gtm.ts
Associates matched network requests with their tab URL and initiator/referrer. — background.bundle.js:background/modules/web-request-handler.ts
Sends separately generated extension feature/error events to its own GA property. — background.bundle.js:global/utils/ga4.ts
Does it create a persistent ID or browser fingerprint to recognize you?
A randomly generated 50-character client ID persists in extension storage and links TagHound's own telemetry over time. Events also carry country/city; a paid license additionally stores a stable key and purchaser email.
Defines a 50-character client ID and sends it as Google Analytics client_id. — background.bundle.js:global/config.ts and global/utils/ga4.ts
Generates and persists ClientId and UserGeoInfo. — background.bundle.js:background store app-slice and startup
Stores the verified license key, purchaser email, sale timestamp, type, and usage state. — option.bundle.js:taghound-plus license activation
Does it send cookies, session details, authentication data, or page contents elsewhere?
It does not read website login cookies or browser passwords, but its paid tier handles a reusable Gumroad license key and purchaser email. The key is sent to Gumroad for verification and, when sharing is suspected, the key/email and purchase metadata are sent to Make.com webhooks.
Accepts a license key and stores the returned purchaser identity and purchase fields. — option.bundle.js:taghound-plus license activation
Posts the key to Gumroad and license/purchaser records to third-party reporting hooks. — background.bundle.js:global/service/modules/license/index.ts
Does it record typing, form entries, clipboard contents, or screenshots?
It can observe analytics request bodies and dataLayer values on any page. Those can contain searches, purchases, products, advertising IDs, hashed email fields, or arbitrary site-defined event data.
Reads raw requestBody bytes and request headers for supported analytics endpoints. — background.bundle.js:background/modules/web-request-handler.ts
Copies arbitrary fields from new dataLayer items into local eventData. — mainWorldContentScript.bundle.js:contentScript/component/gtm.ts
Recognizes search, add-to-cart, checkout, purchase, product, conversion, and contact-related analytics parameters. — background.bundle.js:pixel platform parser modules
Can a website or remote server send commands that make the extension take actions?
No evidence of this behavior was found in the reviewed package.
Fetches and stores a fixed announcement schema after sanitizing message fields. — background.bundle.js:global/service/index.ts and message-handler.ts
Accepts a fixed enum of internal content-script actions rather than server-defined commands. — background.bundle.js:background message-handler.ts
Does it alter links, referral codes, advertisements, shopping carts, or search results?
No evidence of this behavior was found in the reviewed package.
Adds only extension debugger frames. — contentScript.bundle.js:toast.ts and iframe-manager.ts
Opens packaged or user-selected TagHound links in new tabs. — background.bundle.js:misc.ts and openLink listener
Does it redirect or modify web traffic, request headers, downloads, or proxy settings?
It observes request bodies before matched analytics requests, outgoing request headers, completion/error status, initiator/referrer, and timing. It does not block, redirect, or modify those requests; the scripting services is used to obtain the tab's current URL for correlation.
Registers onBeforeRequest, onSendHeaders, onCompleted, and onErrorOccurred over the fixed analytics URL list and captures requestBody/requestHeaders. — background.bundle.js:background/modules/web-request-handler.ts
Can it communicate with software on the computer or services running on localhost?
No evidence of this behavior was found in the reviewed package.
No nativeMessaging permission or loopback host is declared. — manifest.json:permissions and host_permissions
Does it decode, decrypt, or unpack hidden data and then execute or inject it?
No evidence of this behavior was found in the reviewed package.
Runs only fixed packaged source. — background.bundle.js:Webpack runtime global fallback
Treats remote JSON as location, license, or sanitized announcement data. — background.bundle.js:global/service/index.ts and message-handler.ts
Can ordinary websites access privileged extension features through messaging or exposed files?
No evidence of this behavior was found in the reviewed package.
Exposes inject assets and toast pages to <all_urls> and starts mainWorldContentScript.bundle.js in MAIN world. — manifest.json:content_scripts and web_accessible_resources
Loads the exposed extension iframe pages into arbitrary sites. — contentScript.bundle.js:iframe-manager.ts
Does suspicious behavior activate only for certain users, websites, dates, or remote settings?
No evidence of this behavior was found in the reviewed package.
Downloads pixelhelper_pub/main/message.json. — background.bundle.js:global/service/index.ts
Formats message expiration/content and stores it as cloud display data. — background.bundle.js:message-handler.ts and global/util.ts formatCloudMessage
Does it perform hidden resource-intensive work, such as cryptocurrency mining?
No evidence of this behavior was found in the reviewed package.
Checks for new dataLayer events on a one-second cadence while tracking. — mainWorldContentScript.bundle.js:contentScript/component/gtm.ts
Maintains four browser-wide listeners over numerous analytics endpoint patterns. — background.bundle.js:background/modules/web-request-handler.ts
Requests unlimitedStorage for retained debugger/recording state. — manifest.json:permissions
Does it change form fields or where a form sends its information?
No evidence of this behavior was found in the reviewed package.
Registers observational webRequest listeners with no blocking or request-modification return values. — background.bundle.js:background/modules/web-request-handler.ts
Creates debugger UI without altering site forms. — contentScript.bundle.js:toast.ts and iframe-manager.ts