Timezone and Geolocation Spoofing
Relevant source files
The following files were used as context for generating this wiki page:
The Timezone Spoofing feature in GeekEZ Browser is a critical component of its anti-fingerprinting capabilities. It allows each browser profile to present a specific timezone, independent of the host machine's actual timezone. This is essential for making a profile appear authentically located in a specific geographic region, aligning with the profile's proxy IP address to defeat consistency checks performed by advanced detection systems.
While the feature is described as "Timezone & Geo", the implementation within the source code focuses exclusively on comprehensive timezone spoofing. There is no evidence of navigator.geolocation (latitude/longitude) spoofing. The system works by allowing a user to select a timezone, saving it to the profile's fingerprint, and then injecting a sophisticated JavaScript payload at runtime to hook and modify the behavior of the browser's Date and Internationalization (Intl) APIs.
Sources: README.md, fingerprint.js
Feature Overview
The timezone spoofing process is integrated into the profile creation and launch lifecycle. When a user creates or edits a profile, they can select a timezone from a predefined list. This selection is stored within the profile's fingerprint data. Upon launching the profile, this timezone value is used to generate a JavaScript script that is injected into every webpage via a temporary extension, ensuring all time-related browser APIs report the spoofed value.
The following diagram illustrates the high-level flow of this process.
Configuration and Storage
Timezone Data Source
The list of available timezones is provided by a static array in timezones.js. This file contains a comprehensive list of IANA timezone names, ensuring global coverage. This array is made available to the renderer process by attaching it to the window object.
// timezones.js
const TIMEZONES = [
// --- North America ---
"America/New_York", // US Eastern
"America/Chicago", // US Central
"America/Los_Angeles", // US Pacific
// ... and many more
];
if (typeof module !== "undefined") module.exports = TIMEZONES;
else window.TIMEZONES = TIMEZONES;
Sources: timezones.js:2-130
User Interface
The user selects a timezone through a custom, searchable dropdown menu in the "New Profile" and "Edit Profile" modals. This UI is defined in index.html and managed by renderer.js.
- HTML Structure: A wrapper
divcontains a textinputfor searching and adivthat acts as the dropdown list. - Functionality: The
initCustomTimezoneDropdownfunction inrenderer.jspopulates the dropdown fromwindow.TIMEZONES, handles filtering as the user types, and manages keyboard navigation.
<!-- index.html: Add/Edit Profile Modals -->
<label data-i18n="timezoneLabel" style="font-size:11px; font-weight:bold; opacity:0.8;">Timezone</label>
<div class="timezone-wrapper">
<input type="text" id="addTimezone" placeholder="Type to search or select..." autocomplete="off">
<div class="timezone-dropdown" id="addTimezoneDropdown"></div>
</div>
Sources: index.html:884-889, 912-915, renderer.js:1083-1168
Profile Storage
When a new profile is created, the selected timezone is included in the data sent to the main process. The saveProfile handler in main.js incorporates this into the fingerprint object. If no timezone is selected, it defaults to America/Los_Angeles. This fingerprint, including the timezone, is then saved to profiles.json.
renderer.js:saveNewProfile()reads the value from the timezone input.main.js:ipcMain.handle('save-profile', ...)receives the data and setsfingerprint.timezone.
// main.js
ipcMain.handle('save-profile', async (event, data) => {
// ...
const fingerprint = data.fingerprint || generateFingerprint();
if (data.timezone) fingerprint.timezone = data.timezone;
else fingerprint.timezone = "America/Los_Angeles";
const newProfile = { /*...,*/ fingerprint: fingerprint, /*...*/ };
// ...
await fs.writeJson(PROFILES_FILE, profiles);
return newProfile;
});
Sources: main.js:260-262, renderer.js:596, fingerprint.js:97
Spoofing Implementation
The core of the spoofing mechanism is a JavaScript payload that is dynamically generated and injected into the browser at launch.
Injection via Temporary Extension
Instead of a simple script injection, GeekEZ Browser packages the spoofing logic into a temporary manifest v3 Chrome extension named "GeekEZ Guard". This is a more robust and modern approach.
- When a profile is launched,
main.jscallsgenerateExtension(). - This function creates a directory for the extension within the profile's folder.
- It writes a
manifest.jsonfile and acontent.jsfile. - The
content.jscontains the spoofing script generated bygetInjectScript(). - The browser is then launched with the
--load-extensionflag pointing to this temporary extension.
This sequence diagram shows the interactions during profile launch.
Sources: main.js:101-112, 396-400, 428-429
Core Spoofing Logic: JavaScript Hooking
The getInjectScript function in fingerprint.js is responsible for generating the JavaScript code that performs the spoofing. It achieves this by "hooking" or replacing the original implementations of several key JavaScript functions.
The following table summarizes the hooked objects and their purpose.
| Hooked Object/Method | Purpose |
|---|---|
Intl.DateTimeFormat | Wraps the constructor to forcibly inject the timeZone option, ensuring all internationalization functions use the spoofed timezone. |
Date.prototype.getTimezoneOffset | Overridden to calculate and return the correct minute offset from UTC for the spoofed timezone, rather than the host's. |
Date.prototype.toString | Overridden to format the date string according to the spoofed timezone, mimicking native browser behavior. |
Sources: fingerprint.js:102-171
Intl.DateTimeFormat Hook
The script replaces the Intl.DateTimeFormat constructor with a proxy. When a webpage calls new Intl.DateTimeFormat(), the proxy intercepts the call, adds or overwrites the timeZone property in the options object with the target timezone, and then calls the original constructor. This ensures any date/time formatting is done relative to the spoofed location.
// fingerprint.js: Snippet of Intl.DateTimeFormat hook
const OriginalDateTimeFormat = Intl.DateTimeFormat;
Intl.DateTimeFormat = function(locales, options) {
if (!options) options = {};
// Forcefully modify the timezone
if (!options.timeZone) {
options.timeZone = targetTimezone;
}
return new OriginalDateTimeFormat(locales, options);
};
// Restore prototype chain to avoid detection
Intl.DateTimeFormat.prototype = OriginalDateTimeFormat.prototype;
Sources: fingerprint.js:112-122
Date.prototype.getTimezoneOffset Hook
This function is expected to return the difference, in minutes, between UTC and the local time. The original function would return the host machine's offset. The script replaces it with a function that uses toLocaleString with the target timezone to derive the correct offset from the resulting GMT string (e.g., "GMT-08:00").
// fingerprint.js: Snippet of getTimezoneOffset hook
Date.prototype.getTimezoneOffset = function() {
// Use Intl to format a string with the target timezone's offset
const dateString = this.toLocaleString('en-US', { timeZone: targetTimezone, timeZoneName: 'longOffset' });
const match = dateString.match(/GMT([+-]\d{2}):(\d{2})/);
if (match) {
const hours = parseInt(match[1], 10);
const minutes = parseInt(match[2], 10);
// The offset is inverted (e.g., UTC+8 is -480)
return -(hours * 60 + (hours > 0 ? minutes : -minutes));
}
// Fallback
return 420;
};
Sources: fingerprint.js:125-139
Date.prototype.toString Hook
Simply calling new Date() in the browser console prints a detailed string that includes the timezone. To ensure consistency, this method is also hooked. The new implementation uses Intl.DateTimeFormat with the spoofed timezone to generate a full date and time string that matches the target location.
// fingerprint.js: Snippet of toString hook
Object.defineProperty(Date.prototype, 'toString', {
value: function() {
return new Intl.DateTimeFormat('en-US', {
dateStyle: 'full',
timeStyle: 'long',
timeZone: targetTimezone
}).format(this);
}
});
Sources: fingerprint.js:161-169
Conclusion
The Timezone Spoofing system in GeekEZ Browser is a robust, multi-layered feature that effectively alters the browser's perception of time. By combining user configuration, persistent storage in the profile's fingerprint, and a sophisticated runtime injection mechanism that hooks multiple JavaScript APIs, it ensures that a profile's timezone is consistently and convincingly reported as the desired value. This is a fundamental technique for passing the consistency checks employed by modern fingerprinting services and maintaining profile integrity.