mirror of
https://forge.fsky.io/oneflux/omegafox.git
synced 2026-02-10 07:02:03 -08:00
Add locale spoofing #16 beta.8
Spoof the Intl API, headers, and system locale values. Added the following properties: - locale:language - locale:region - locale:script
This commit is contained in:
parent
809dc52207
commit
5263cb6305
5 changed files with 237 additions and 24 deletions
26
README.md
26
README.md
|
|
@ -126,6 +126,7 @@ Camoufox will automatically add the following default fonts associated your spoo
|
|||
**Notes**:
|
||||
|
||||
- **navigator.webdriver** is set to false at all times.
|
||||
- `navigator.language` & `navigator.languages` will fall back to the `locale:language`/`locale:region` values if not set.
|
||||
- When spoofing Chrome fingerprints, the following may leak:
|
||||
- navigator.userAgentData missing.
|
||||
- navigator.deviceMemory missing.
|
||||
|
|
@ -264,21 +265,26 @@ Camoufox can override the following network headers:
|
|||
|
||||
<details>
|
||||
<summary>
|
||||
Geolocation
|
||||
Geolocation & Intl
|
||||
</summary>
|
||||
|
||||
| Property | Status | Description |
|
||||
| --------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| geolocation:latitude | ✅ | Latitude to use. Requires `geolocation:longitude` to be set as well. |
|
||||
| geolocation:longitude | ✅ | Longitude to use. Requires `geolocation:longitude` to be set as well. |
|
||||
| geolocation:accuracy | ✅ | Accuracy in meters. This will be calculated automatically using the decminal percision of `geolocation:latitude` & `geolocation:longitude` if not set. |
|
||||
| timezone | ✅ | Set a custom TZ timezone (e.g. "America/Chicago"). This will also change `Date()` to return the local time. |
|
||||
| Property | Status | Description | Required Keys |
|
||||
| --------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- |
|
||||
| geolocation:latitude | ✅ | Latitude to use. | `geolocation:longitude` |
|
||||
| geolocation:longitude | ✅ | Longitude to use. | `geolocation:latitude` |
|
||||
| geolocation:accuracy | ✅ | Accuracy in meters. This will be calculated automatically using the decminal percision of `geolocation:latitude` & `geolocation:longitude` if not set. | |
|
||||
| timezone | ✅ | Set a custom TZ timezone (e.g. "America/Chicago"). This will also change `Date()` to return the local time. | |
|
||||
| locale:language | ✅ | Spoof the Intl API, headers, and system language (e.g. "en") | `locale:region` |
|
||||
| locale:region | ✅ | Spoof the Intl API, headers, and system region (e.g. "US"). | `locale:language` |
|
||||
| locale:script | ✅ | Set a custom script (e.g. "Latn"). Will be set automatically if not specified. | |
|
||||
|
||||
The **Required Keys** are keys that must also be set for the property to work.
|
||||
|
||||
**Notes:**
|
||||
|
||||
- Setting `geolocation:latitude` & `geolocation:longitude` will automatically accept Location permission prompts.
|
||||
- Location permission prompts will be accepted automatically if `geolocation:latitude` and `geolocation:longitude` are set.
|
||||
- `timezone` **must** be set to a valid TZ identifier. See [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for a list of valid timezones.
|
||||
- To change your locale, set the `intl.accept_languages` preference.
|
||||
- `locale:language` & `locale:region` **must** be set to valid locale values. See [here](https://simplelocalize.io/data/locales/) for a list of valid locale-region values.
|
||||
|
||||
</details>
|
||||
|
||||
|
|
@ -406,7 +412,7 @@ Miscellaneous (battery status, etc)
|
|||
- Support for spoofing both inner and outer window viewport sizes
|
||||
- Network headers (Accept-Languages and User-Agent) are spoofed to match the navigator properties
|
||||
- WebRTC IP spoofing at the protocol level
|
||||
- Geolocation & timezone spoofing
|
||||
- Geolocation, timezone, and locale spoofing
|
||||
- etc.
|
||||
|
||||
#### Anti font fingerprinting
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/dom/base/ChromeUtils.cpp b/dom/base/ChromeUtils.cpp
|
||||
index 6833d2227f..d3d2ef088d 100644
|
||||
index 6833d2227f..0b2ea99615 100644
|
||||
--- a/dom/base/ChromeUtils.cpp
|
||||
+++ b/dom/base/ChromeUtils.cpp
|
||||
@@ -5,6 +5,7 @@
|
||||
|
|
@ -10,13 +10,12 @@ index 6833d2227f..d3d2ef088d 100644
|
|||
|
||||
#include "JSOracleParent.h"
|
||||
#include "js/CallAndConstruct.h" // JS::Call
|
||||
@@ -2068,6 +2069,25 @@ bool ChromeUtils::IsDarkBackground(GlobalObject&, Element& aElement) {
|
||||
@@ -2068,6 +2069,24 @@ bool ChromeUtils::IsDarkBackground(GlobalObject&, Element& aElement) {
|
||||
return nsNativeTheme::IsDarkBackground(f);
|
||||
}
|
||||
|
||||
+/* static */
|
||||
+void ChromeUtils::CamouDebug(GlobalObject& aGlobal,
|
||||
+ const nsAString& aVarName) {
|
||||
+void ChromeUtils::CamouDebug(GlobalObject& aGlobal, const nsAString& aVarName) {
|
||||
+ if (auto value = MaskConfig::GetBool("debug");
|
||||
+ value.has_value() && !value.value()) {
|
||||
+ return;
|
||||
|
|
@ -36,7 +35,7 @@ index 6833d2227f..d3d2ef088d 100644
|
|||
double ChromeUtils::DateNow(GlobalObject&) { return JS_Now() / 1000.0; }
|
||||
|
||||
/* static */
|
||||
@@ -2094,6 +2114,28 @@ void ChromeUtils::GetAllPossibleUtilityActorNames(GlobalObject& aGlobal,
|
||||
@@ -2094,6 +2113,39 @@ void ChromeUtils::GetAllPossibleUtilityActorNames(GlobalObject& aGlobal,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,12 +60,23 @@ index 6833d2227f..d3d2ef088d 100644
|
|||
+ return aDefaultValue;
|
||||
+}
|
||||
+
|
||||
+/* static */
|
||||
+void ChromeUtils::CamouGetString(GlobalObject& aGlobal,
|
||||
+ const nsAString& aVarName,
|
||||
+ nsAString& aRetVal) {
|
||||
+ NS_ConvertUTF16toUTF8 utf8VarName(aVarName);
|
||||
+ if (auto value = MaskConfig::GetString(utf8VarName.get())) {
|
||||
+ aRetVal.Assign(NS_ConvertUTF8toUTF16(value.value()));
|
||||
+ } else {
|
||||
+ aRetVal.Truncate();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* static */
|
||||
bool ChromeUtils::ShouldResistFingerprinting(
|
||||
GlobalObject& aGlobal, JSRFPTarget aTarget,
|
||||
diff --git a/dom/base/ChromeUtils.h b/dom/base/ChromeUtils.h
|
||||
index 0150c59670..d297ab5788 100644
|
||||
index 0150c59670..e3d203ed1a 100644
|
||||
--- a/dom/base/ChromeUtils.h
|
||||
+++ b/dom/base/ChromeUtils.h
|
||||
@@ -301,6 +301,10 @@ class ChromeUtils {
|
||||
|
|
@ -80,7 +90,7 @@ index 0150c59670..d297ab5788 100644
|
|||
static double DateNow(GlobalObject&);
|
||||
|
||||
static void EnsureJSOracleStarted(GlobalObject&);
|
||||
@@ -310,6 +314,11 @@ class ChromeUtils {
|
||||
@@ -310,6 +314,14 @@ class ChromeUtils {
|
||||
static void GetAllPossibleUtilityActorNames(GlobalObject& aGlobal,
|
||||
nsTArray<nsCString>& aNames);
|
||||
|
||||
|
|
@ -88,12 +98,15 @@ index 0150c59670..d297ab5788 100644
|
|||
+
|
||||
+ static double CamouGetDouble(GlobalObject& aGlobal, const nsAString& aVarName,
|
||||
+ double aDefaultValue);
|
||||
+
|
||||
+ static void CamouGetString(GlobalObject& aGlobal, const nsAString& aVarName,
|
||||
+ nsAString& aRetVal);
|
||||
+
|
||||
static bool ShouldResistFingerprinting(
|
||||
GlobalObject& aGlobal, JSRFPTarget aTarget,
|
||||
const Nullable<uint64_t>& aOverriddenFingerprintingSettings);
|
||||
diff --git a/dom/chrome-webidl/ChromeUtils.webidl b/dom/chrome-webidl/ChromeUtils.webidl
|
||||
index bf196f039d..994b5803df 100644
|
||||
index bf196f039d..04e0cdcabd 100644
|
||||
--- a/dom/chrome-webidl/ChromeUtils.webidl
|
||||
+++ b/dom/chrome-webidl/ChromeUtils.webidl
|
||||
@@ -746,6 +746,13 @@ partial namespace ChromeUtils {
|
||||
|
|
@ -110,7 +123,7 @@ index bf196f039d..994b5803df 100644
|
|||
/**
|
||||
* Starts the JSOracle process for ORB JavaScript validation, if it hasn't started already.
|
||||
*/
|
||||
@@ -757,6 +764,16 @@ partial namespace ChromeUtils {
|
||||
@@ -757,6 +764,21 @@ partial namespace ChromeUtils {
|
||||
[ChromeOnly]
|
||||
readonly attribute unsigned long aliveUtilityProcesses;
|
||||
|
||||
|
|
@ -123,6 +136,11 @@ index bf196f039d..994b5803df 100644
|
|||
+ * Get a double value from Camoufox MaskConfig.
|
||||
+ */
|
||||
+ double camouGetDouble(DOMString varName, double defaultValue);
|
||||
+
|
||||
+ /**
|
||||
+ * Get a string value from Camoufox MaskConfig.
|
||||
+ */
|
||||
+ DOMString camouGetString(DOMString varName);
|
||||
+
|
||||
/**
|
||||
* Get a list of all possible Utility process Actor Names ; mostly useful to
|
||||
|
|
|
|||
186
patches/locale-spoofing.patch
Normal file
186
patches/locale-spoofing.patch
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
diff --git a/browser/base/content/browser-init.js b/browser/base/content/browser-init.js
|
||||
index 16f4dd7d42..63c9c39741 100644
|
||||
--- a/browser/base/content/browser-init.js
|
||||
+++ b/browser/base/content/browser-init.js
|
||||
@@ -109,6 +109,17 @@ var gBrowserInit = {
|
||||
window.TabBarVisibility.update();
|
||||
TabsInTitlebar.init();
|
||||
|
||||
+ let camouLocale;
|
||||
+ let language = ChromeUtils.camouGetString("locale:language");
|
||||
+ let region = ChromeUtils.camouGetString("locale:region");
|
||||
+ if (language && region) {
|
||||
+ camouLocale = language + "-" + region + ", " + language;
|
||||
+ } else {
|
||||
+ camouLocale = ChromeUtils.camouGetString("navigator.language");
|
||||
+ }
|
||||
+ if (camouLocale)
|
||||
+ Services.prefs.setCharPref("intl.accept_languages", camouLocale);
|
||||
+
|
||||
new LightweightThemeConsumer(document);
|
||||
|
||||
if (
|
||||
diff --git a/intl/components/src/Locale.cpp b/intl/components/src/Locale.cpp
|
||||
index 9a043518cf..a8d3733212 100644
|
||||
--- a/intl/components/src/Locale.cpp
|
||||
+++ b/intl/components/src/Locale.cpp
|
||||
@@ -24,11 +24,56 @@
|
||||
|
||||
#include "unicode/uloc.h"
|
||||
#include "unicode/utypes.h"
|
||||
+#include "MaskConfig.hpp"
|
||||
|
||||
namespace mozilla::intl {
|
||||
|
||||
using namespace intl::LanguageTagLimits;
|
||||
|
||||
+
|
||||
+// Helper methods for header file
|
||||
+
|
||||
+const char* Locale::GetCamouLanguage() {
|
||||
+ if (auto lang = MaskConfig::GetString("locale:language"))
|
||||
+ return lang.value().c_str();
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
+const char* Locale::GetCamouRegion() {
|
||||
+ if (auto region = MaskConfig::GetString("locale:region"))
|
||||
+ return region.value().c_str();
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
+const char* Locale::GetCamouScript() {
|
||||
+ if (auto script = MaskConfig::GetString("locale:script"))
|
||||
+ return script.value().c_str();
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
+// Publicly exposed methods
|
||||
+
|
||||
+const char* Locale::GetCamouLocale() {
|
||||
+ static std::string locale;
|
||||
+
|
||||
+ if (auto lang = MaskConfig::GetString("locale:language"))
|
||||
+ if (auto region = MaskConfig::GetString("locale:region"))
|
||||
+ locale = (lang.value() + "-" + region.value());
|
||||
+ if (auto value = MaskConfig::GetString("navigator.language"))
|
||||
+ locale = value.value();
|
||||
+ if (locale.empty())
|
||||
+ return nullptr;
|
||||
+ return locale.c_str();
|
||||
+}
|
||||
+
|
||||
+const char* Locale::GetDefaultLocale() {
|
||||
+ // In Camoufox, GetDefaultLocale is defined outside the header
|
||||
+ // to access MaskConfig.
|
||||
+ if (auto value = GetCamouLocale())
|
||||
+ return value;
|
||||
+ return uloc_getDefault();
|
||||
+}
|
||||
+
|
||||
template <typename CharT>
|
||||
bool IsStructurallyValidLanguageTag(Span<const CharT> aLanguage) {
|
||||
// unicode_language_subtag = alpha{2,3} | alpha{5,8};
|
||||
diff --git a/intl/components/src/Locale.h b/intl/components/src/Locale.h
|
||||
index 1f4e06f543..448486a479 100644
|
||||
--- a/intl/components/src/Locale.h
|
||||
+++ b/intl/components/src/Locale.h
|
||||
@@ -190,8 +190,11 @@ using UniqueChars = UniquePtr<char[]>;
|
||||
*/
|
||||
class MOZ_STACK_CLASS Locale final {
|
||||
LanguageSubtag mLanguage = {};
|
||||
+ mutable LanguageSubtag mCamouLanguage = {};
|
||||
ScriptSubtag mScript = {};
|
||||
+ mutable ScriptSubtag mCamouScript = {};
|
||||
RegionSubtag mRegion = {};
|
||||
+ mutable RegionSubtag mCamouRegion = {};
|
||||
|
||||
using VariantsVector = Vector<UniqueChars, 2>;
|
||||
using ExtensionsVector = Vector<UniqueChars, 2>;
|
||||
@@ -314,9 +317,28 @@ class MOZ_STACK_CLASS Locale final {
|
||||
}
|
||||
};
|
||||
|
||||
- const LanguageSubtag& Language() const { return mLanguage; }
|
||||
- const ScriptSubtag& Script() const { return mScript; }
|
||||
- const RegionSubtag& Region() const { return mRegion; }
|
||||
+ const LanguageSubtag& Language() const {
|
||||
+ if (const char* lang = GetCamouLanguage()) {
|
||||
+ mCamouLanguage.Set(mozilla::Span<const char>(lang, strlen(lang)));
|
||||
+ return mCamouLanguage;
|
||||
+ }
|
||||
+ return mLanguage;
|
||||
+ }
|
||||
+ const ScriptSubtag& Script() const {
|
||||
+ if (const char* script = GetCamouScript()) {
|
||||
+ mCamouScript.Set(mozilla::Span<const char>(script, strlen(script)));
|
||||
+ return mCamouScript;
|
||||
+ }
|
||||
+ return mScript;
|
||||
+ }
|
||||
+ const RegionSubtag& Region() const {
|
||||
+ if (const char* region = GetCamouRegion()) {
|
||||
+ mCamouRegion.Set(mozilla::Span<const char>(region, strlen(region)));
|
||||
+ return mCamouRegion;
|
||||
+ }
|
||||
+ return mRegion;
|
||||
+ }
|
||||
+
|
||||
auto Variants() const { return SubtagEnumeration(mVariants); }
|
||||
auto Extensions() const { return SubtagEnumeration(mExtensions); }
|
||||
Maybe<Span<const char>> PrivateUse() const {
|
||||
@@ -483,7 +505,15 @@ class MOZ_STACK_CLASS Locale final {
|
||||
*
|
||||
* Also see <https://unicode-org.github.io/icu/userguide/locale>.
|
||||
*/
|
||||
- static const char* GetDefaultLocale() { return uloc_getDefault(); }
|
||||
+ static const char* GetDefaultLocale();
|
||||
+
|
||||
+ static const char* GetCamouLocale();
|
||||
+
|
||||
+ static const char* GetCamouLanguage();
|
||||
+
|
||||
+ static const char* GetCamouRegion();
|
||||
+
|
||||
+ static const char* GetCamouScript();
|
||||
|
||||
/**
|
||||
* Returns an iterator over all supported locales.
|
||||
diff --git a/intl/locale/OSPreferences.cpp b/intl/locale/OSPreferences.cpp
|
||||
index b87924b61a..2eaa960c04 100644
|
||||
--- a/intl/locale/OSPreferences.cpp
|
||||
+++ b/intl/locale/OSPreferences.cpp
|
||||
@@ -406,6 +406,10 @@ bool OSPreferences::GetDateTimeConnectorPattern(const nsACString& aLocale,
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
OSPreferences::GetSystemLocales(nsTArray<nsCString>& aRetVal) {
|
||||
+ if (const char* camouLocale = mozilla::intl::Locale::GetCamouLocale()) {
|
||||
+ aRetVal.AppendElement(camouLocale);
|
||||
+ return NS_OK;
|
||||
+ }
|
||||
if (!mSystemLocales.IsEmpty()) {
|
||||
aRetVal = mSystemLocales.Clone();
|
||||
return NS_OK;
|
||||
@@ -425,7 +429,10 @@ OSPreferences::GetSystemLocales(nsTArray<nsCString>& aRetVal) {
|
||||
|
||||
NS_IMETHODIMP
|
||||
OSPreferences::GetSystemLocale(nsACString& aRetVal) {
|
||||
- if (!mSystemLocales.IsEmpty()) {
|
||||
+ if (const char* camouLocale = mozilla::intl::Locale::GetCamouLocale()) {
|
||||
+ aRetVal = camouLocale;
|
||||
+ return NS_OK;
|
||||
+ } else if (!mSystemLocales.IsEmpty()) {
|
||||
aRetVal = mSystemLocales[0];
|
||||
} else {
|
||||
AutoTArray<nsCString, 10> locales;
|
||||
@@ -439,6 +446,10 @@ OSPreferences::GetSystemLocale(nsACString& aRetVal) {
|
||||
|
||||
NS_IMETHODIMP
|
||||
OSPreferences::GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal) {
|
||||
+ if (const char* camouLocale = mozilla::intl::Locale::GetCamouLocale()) {
|
||||
+ aRetVal.AppendElement(camouLocale);
|
||||
+ return NS_OK;
|
||||
+ }
|
||||
if (!mRegionalPrefsLocales.IsEmpty()) {
|
||||
aRetVal = mRegionalPrefsLocales.Clone();
|
||||
return NS_OK;
|
||||
|
|
@ -58,5 +58,8 @@
|
|||
{ "property": "geolocation:latitude", "type": "double" },
|
||||
{ "property": "geolocation:longitude", "type": "double" },
|
||||
{ "property": "geolocation:accuracy", "type": "double" },
|
||||
{ "property": "timezone", "type": "str" }
|
||||
{ "property": "timezone", "type": "str" },
|
||||
{ "property": "locale:language", "type": "str" },
|
||||
{ "property": "locale:region", "type": "str" },
|
||||
{ "property": "locale:script", "type": "str" }
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
version=130.0.1
|
||||
release=beta.7
|
||||
release=beta.8
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue