Is Toggl Track: Productivity & Time Tracker safe?
We analyzed Toggl Track: Productivity & Time Tracker version 4.11.22's actual code and gave it a 78/100 trust score. This appears to be a legitimate…
Bottom line
This appears to be a legitimate time-tracking extension with moderate access and no established abuse, but it can read selected work-page content and optionally operate across many sites.
What it can access
It can access Toggl data and selected work-page content, while broader site access is optional for integrations.[Q1][Q2][Q3][Q4]
Security weaknesses
Optional broad page access and large bundled code increase exposure and review difficulty, but remote code execution and unsafe public messaging were not found.[Q7][Q10][Q20][Q21]
Signs of misuse
The package shows feature-related data sharing with Toggl and optional analytics, but no evidence of deceptive changes, tracking of browsing, mining or credential theft.[Q6][Q12][Q17][Q23]
Code findings
What access does this extension ask for, and does that access make sense for what it claims to do?
It always has access to Toggl sites and requests cookies, scripting, storage, idle, notifications, context menus and background capabilities. Access to other sites is optional.
Declares Toggl host access, cookies, scripting and other timer permissions, with tabs and all-site host access optional. — manifest.json:18-68
Requests either all-sites or per-integration origin permission in response to settings/onboarding choices and removes it when disabled. — settings.js:1
Default settings contain an empty integrations map, so non-Toggl site integrations are not active by default. — assets/ProjectsCreateService.js:27
Which websites can it run on, and can it read or change what appears on those pages?
On an enabled integration site it injects a packaged base script, stylesheet and site-specific adapter. Adapters read work-item titles, project names, tags and nearby page structure, then insert a visible Toggl timer control.
On completed tab loads, checks enabled integration and custom-script settings before injecting packaged content/index.js, CSS and the selected packaged adapter. — background.js:1
Reads GitHub issue or pull-request context and inserts a Toggl timer button. — src/content/github.js:1
Adds the timer integration to the supported Gmail interface. — src/content/google-mail.js:1
Can it see sensitive information you type, such as passwords, payment details, messages, or form entries?
Enabled adapters can read potentially private work content such as issue titles, email context, CRM ticket names, project names and tags for use as time-entry descriptions. That is the advertised feature.
Builds timer controls from adapter-provided description, project and tag callbacks, and dispatches the resulting time entry to the background service. — src/content/index.js:2289
Reads ticket-number and title fields to construct a timer description. — src/content/dynamics-365.js:1
Reads a note title and notebook name for the visible timer entry. — src/content/evernote.js:1
Can it access private browser data such as cookies, signed-in sessions, browsing history, bookmarks, or downloads?
It has cookie access for Toggl domains and reads the `__Secure-accounts-session` cookie from track.toggl.com. The cookie is used as an OAuth-style token to authenticate only to `wss://track.toggl.com/stream`.
Grants cookies permission together with host access limited by default to Toggl domains. — manifest.json:27-51
Reads the named secure Toggl accounts session cookie and sends it in an authenticate message to Toggl's own WebSocket. — background.js:1
Can it access anything else on your device, such as files, location, camera, microphone, clipboard, or installed applications?
It reads the browser's idle state to offer idle-time handling for active timers and uses an offscreen document only to play Pomodoro sounds. No access to arbitrary device files, location, camera, microphone, clipboard or installed applications was found.
Declares idle and offscreen permissions but not file-system, geolocation, camera, microphone, clipboard or management permissions. — manifest.json:27-51
The offscreen handler only plays and stops packaged audio requested for Pomodoro alerts. — offscreen.js:1
Uses idle-state changes to offer stopping or adjusting the user's active time entry. — background.js:1
Does it send information outside your browser? If so, what information is sent, where does it go, and why?
Timer descriptions, project/task identifiers, tags, timing and billable state are sent to Toggl's extension/services services to store the user's time entries. Opted-in PostHog analytics receives account-linked product events such as integration origin/name, browser version and permission counts.
Creates and updates time entries through the Toggl API and emits daily product telemetry keyed by toggl_accounts_id. — background.js:1
Dispatches chosen description/project/tag data to start-entry and sends integration and auto-tracking events through the PostHog client. — src/content/index.js:2289
Configures Sentry and the EU PostHog endpoint with consent checks and telemetry filtering. — assets/ProjectsCreateService.js:27, 60
Does it download or run code, settings, or instructions supplied by a remote server?
Toggl supplies account records, workspaces, projects, tags, time entries and real-time WebSocket updates that control the extension's displayed state. The extension treats them as structured product data.
Parses Toggl WebSocket JSON and dispatches recognized model updates into local Toggl stores. — background.js:1
Selects injected adapter filenames from packaged integration metadata and locally stored choices, then calls scripting.executeScript with extension files. — background.js:1
Custom workflow UI selects from packaged integration-script options rather than downloading JavaScript. — settings.js:37
Can it take actions without a clear user request, such as opening pages, redirecting searches, downloading files, or sending requests?
The extension can automatically start or stop time entries, remind the user to track, react to browser idle state and open a changelog after update. These behaviors are visible product features and are disabled by default or controlled in settings.
Defaults automatic start/stop, reminders, idle detection, track-remind and auto-tracking settings to false. — assets/ProjectsCreateService.js:27
Stores and checks per-origin auto-tracker opt-in before automatically creating entries. — src/content/index.js:2289
Implements configured start/stop, idle, reminder, update-changelog and context-menu behaviors. — background.js:1
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.
Declared and optional permissions do not include proxy, search-provider, homepage or browser-settings control. — manifest.json:27-57
Is any important behavior difficult to inspect because the code is hidden, heavily obfuscated, dynamically generated, or supplied by third parties?
Core UI and shared-library bundles are very large and minified, which makes independent review harder, while the many small site adapters remain readable. Minification and bundled dependencies are not evidence of malicious behavior, and the important permission, injection, network, analytics and messaging paths were traceable.
A roughly 4.2 MB bundle combines the content framework, API client, telemetry libraries and timer UI. — src/content/index.js:1-2289
Individual integration logic is shipped as short readable packaged scripts. — src/content/github.js:1
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.
Bundled utilities use the fixed return-this expression as a global-object fallback. — src/content/index.js:1768, 1963
Contains equivalent packaged compatibility fallbacks; none accepts runtime input. — assets/client.js:1731, 1926
Does it track the websites, pages, searches, or links you visit?
No evidence of this behavior was found in the reviewed package.
Checks active/updated tab URLs only to decide whether a configured local track reminder should appear. — sw.js:1
Uses the current URL locally for enabled integration selection and optional remember-project-per-URL storage. — background.js:1
PostHog disables referrer saving and denies current URL, host, pathname and referrer properties. — assets/ProjectsCreateService.js:60
Does it create a persistent ID or browser fingerprint to recognize you?
Toggl's own account identifiers are used for services data, daily activity telemetry and product events. PostHog can therefore associate opted-in analytics with the Toggl account.
Uses toggl_accounts_id as the PostHog distinctId for a bounded daily active event. — background.js:1
Uses the same account identifier for integration and auto-tracker product events when usage statistics are enabled. — src/content/index.js:2289
Presents usage-statistics and error-reporting controls during onboarding and in Telemetry settings. — settings.js:1, 37
Does it send cookies, session details, authentication data, or page contents elsewhere?
It sends time-entry content and authentication material only to the Toggl services the user is actively using. Specifically, the Toggl session cookie authenticates Toggl's own WebSocket, and the Toggl services token authenticates Toggl services requests.
Reads the named Toggl session cookie and sends it only in the authentication message to wss://track.toggl.com/stream. — background.js:1
Adds the stored Toggl API token as Basic authentication for Toggl Track API requests. — assets/ProjectsCreateService.js:19
Configures bounded Sentry/PostHog telemetry with consent checks, URL filtering and session recording disabled. — assets/ProjectsCreateService.js:27, 60
Does it record typing, form entries, clipboard contents, or screenshots?
Some enabled adapters read visible task-title input values or selected page text to prefill a time-entry description. That is user-facing integration behavior, not a general keystroke monitor.
Uses the user's selectedText only when the visible context-menu timer command is chosen. — background.js:1
Reads ticket title inputs on the specifically enabled Dynamics integration to form a timer description. — src/content/dynamics-365.js:1
Does not request clipboard or desktop/screenshot capture permissions. — manifest.json:27-57
Can a website or remote server send commands that make the extension take actions?
Toggl's WebSocket supplies recognized time-entry, project, tag, task and workspace changes that update the local timer state. services responses likewise control displayed account data.
Parses WebSocket JSON and switches over recognized model names before updating the corresponding local data stores. — background.js:1
Unknown WebSocket models are logged rather than dispatched to a generic evaluator. — background.js:1
Does it alter links, referral codes, advertisements, shopping carts, or search results?
No evidence of this behavior was found in the reviewed package.
Contains visible links to Toggl web app, reports, plans, surveys and Toggl Focus products. — src/pages/popup/index.js:1, 15
Creates recognizable Toggl timer controls within enabled integration pages. — src/content/index.js:2289
Does it redirect or modify web traffic, request headers, downloads, or proxy settings?
No evidence of this behavior was found in the reviewed package.
Does not declare proxy, webRequest, declarativeNetRequest or downloads permissions. — manifest.json:27-57
Directs its API client to fixed Toggl-owned service hosts. — assets/ProjectsCreateService.js:19
Can it communicate with software on the computer or services running on localhost?
No evidence of this behavior was found in the reviewed package.
Does not request nativeMessaging or local-network-specific permissions. — manifest.json:27-57
Configured runtime service endpoints are HTTPS Toggl, Sentry and PostHog hosts rather than localhost or private-network addresses. — assets/ProjectsCreateService.js:19, 27, 60
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.
Packaged hashing and PostHog compression code treats inputs as data. — src/content/index.js:2282-2289
Injects only packaged adapter file paths selected from local integration settings. — background.js:1
Can ordinary websites access privileged extension features through messaging or exposed files?
No evidence of this behavior was found in the reviewed package.
Mints a 100-byte random channel token in the extension runtime and requires it before forwarding ports to a worker. — worker_proxy.js:42-140, 142-270
Accepts page messages only from the same window and origin. — login.js:1
Checks the sender URL before VERIFY_USER or CLEAR_DATA actions from the Toggl login bridge. — background.js:1
Restricts externally connectable pages to Toggl domains while exposing settings and the token-protected worker frame. — manifest.json:59-68, 73-91
Does suspicious behavior activate only for certain users, websites, dates, or remote settings?
No evidence of this behavior was found in the reviewed package.
Lists the advertised supported integrations and their packaged adapter filenames. — assets/origins.js:1
Shows integration controls and requests the corresponding optional host permission. — settings.js:1, 37
Injects adapters only when the current domain is enabled in stored integration settings. — background.js:1
Does it perform hidden resource-intensive work, such as cryptocurrency mining?
No evidence of this behavior was found in the reviewed package.
Uses alarms for synchronization, reminders, Pomodoro, WebSocket health and one daily telemetry event. — background.js:1
Mutation observers look for integration UI targets and debounce repeated page changes. — src/content/index.js:2289
Does it change form fields or where a form sends its information?
No evidence of this behavior was found in the reviewed package.
Reads task-related input title/text to build a timer description and appends a Toggl control; it does not change the form destination. — src/content/dynamics-365.js:1
Reads the mailing-name value for the user-visible time-entry description without altering submission behavior. — src/content/newsletter2go.js:1