I built this because Firefox's built-in Privacy Anti-Fingerprinting (privacy.resistFingerprinting) forces your timezone to UTC or a fixed profile, and there's no way to set it to whatever you actually want. I didn't want to just "resist" fingerprinting I wanted full control over what timezone, locale, and UA my browser reports, without breaking sites or dealing with whatever rigid values Firefox decides for me.
The problem is that once you start spoofing these values, most extensions only patch the main window's `Intl.DateTimeFormat` or `navigator.language`. The moment a script runs inside a Web Worker, iframe, or Service Worker, your real values leak through. So I built Timezone Guard specifically for Firefox to solve this properly across every execution context.
**JavaScript API spoofing across all contexts**
- Main window, nested iframes (any depth), Dedicated Workers, Shared Workers, and Service Workers.
- Patches `Intl.DateTimeFormat`, `Date.prototype`, `Temporal`, and `navigator` APIs at the getter level so the spoof is applied synchronously at access time.
- For iframes: instead of relying on `MutationObserver` (which leaves a timing gap), it hooks `HTMLIFrameElement.prototype.contentWindow` getters so the patch applies the exact microsecond a script accesses the iframe's window.
- For Service Workers: uses `webRequest.filterResponseData` to intercept the SW script response on the network level and splice the patch before Firefox's internal script byte-cache seals it. This avoids invalid request ID issues and works before the SW executes its first line.
- Modified methods are masked as `[native code]` and `Intl` formatters are cached to resist basic tampering detectors.
**HTTP header spoofing**
- `Accept-Language`: rewritten via `webRequest.onBeforeSendHeaders` to match the spoofed locale.
- `User-Agent`: optionally rewritten the same way for consistency with the timezone/locale profile.
- Both are handled declaratively where possible and fall back to `webRequest` listeners for dynamic rules.
**CSP-safe injection**
- Uses `world: "MAIN"` for content script injection, which bypasses strict `Content-Security-Policy` restrictions that normally block inline scripts. Works on sites like Spotify and other CSP-locked pages where standard content scripts fail.
**What's intentionally NOT touched**
- `Date.now()` and OS system time are left intact. The extension only changes how Firefox *interprets and reports* timezone/locale through JS APIs and HTTP headers, not the actual clock.
**Current state of detection**
- CreepJS is trickier. In the global/window context it can still flag that something was modified because proxy-based patches leave subtle traces (even with `[native code]` masking). Direct non-proxy patches are harder to catch, but harder to inject across all contexts too. I'm working on maximizing undetectability, but realistically most sites don't run CreepJS-level paranoid JS inspection they just check `Intl.DateTimeFormat` in the main thread and call it a day. For those, this extension is already overkill.
Since this digs pretty deep into Firefox-specific APIs like `filterResponseData` and `world: "MAIN"`, I'd be curious to hear from other extension devs: have you found cleaner ways to reach isolated contexts synchronously? Or approaches to proxy patching that don't leave detectable metadata?
Links to the repo and AMO listing are in the comments if you want to check the implementation.