328 lines
13 KiB
Python
328 lines
13 KiB
Python
"""Browser identity personas + cookie policies.
|
||
|
||
The "lock everything down" approach (Firefox RFP + WebRTC off + cookies blocked)
|
||
keeps you safe from fingerprinting but makes the machine *look weird* — sites
|
||
flag you as suspicious and ban / captcha you. Worse: very few users use that
|
||
config, so RFP-on is itself a fingerprint.
|
||
|
||
Two strategies are exposed:
|
||
|
||
• **Blend-in personas** — mimic the most common Windows-Chrome-US-en setup.
|
||
JS / cookies / WebGL all work; everything looks normal; only WebRTC is
|
||
blocked (because that leaks the real IP behind the proxy). The proxy
|
||
chain itself does the actual hiding.
|
||
|
||
• **Hardened** — full RFP / blocked WebRTC / strict tracking / FPI. Stand-out
|
||
but maximum block. Same behavior as the original profile.
|
||
|
||
Cookie modes are independent of persona. Each mode expresses a complete
|
||
policy: which cookies to accept, lifetime, whether to wipe on close, and
|
||
whether to partition 3rd-party storage.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
|
||
|
||
# ── Personas ──────────────────────────────────────────────────────────────────
|
||
|
||
PERSONAS: list[str] = [
|
||
"blend_windows_chrome",
|
||
"blend_windows_chrome_laptop",
|
||
"blend_windows_firefox",
|
||
"blend_windows_edge",
|
||
"blend_mac_safari",
|
||
"blend_mac_chrome",
|
||
"blend_linux_firefox",
|
||
"hardened",
|
||
"custom",
|
||
]
|
||
|
||
PERSONA_LABELS: dict[str, str] = {
|
||
"blend_windows_chrome": "Blend — Win10 + Chrome 124 (most common, US-en)",
|
||
"blend_windows_chrome_laptop": "Blend — Win11 + Chrome 124 laptop 1366×768",
|
||
"blend_windows_firefox": "Blend — Win10 + Firefox 128 (US-en)",
|
||
"blend_windows_edge": "Blend — Win11 + Edge 124 (corporate look)",
|
||
"blend_mac_safari": "Blend — macOS 14 + Safari 17 (US-en)",
|
||
"blend_mac_chrome": "Blend — macOS 14 + Chrome 124 (US-en)",
|
||
"blend_linux_firefox": "Blend — Ubuntu + Firefox 128 (en-US)",
|
||
"hardened": "Hardened — RFP + FPI + block all (stands out)",
|
||
"custom": "Custom — use individual hardening toggles",
|
||
}
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class Persona:
|
||
"""A user-agent / locale / timezone / screen tuple that mimics a real,
|
||
common configuration."""
|
||
key: str
|
||
user_agent: str
|
||
accept_language: str
|
||
timezone: str
|
||
screen_w: int
|
||
screen_h: int
|
||
platform: str
|
||
locale: str
|
||
|
||
|
||
PERSONA_DATA: dict[str, Persona] = {
|
||
"blend_windows_chrome": Persona(
|
||
key="blend_windows_chrome",
|
||
user_agent=(
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||
"(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
||
),
|
||
accept_language="en-US,en;q=0.9",
|
||
timezone="America/New_York",
|
||
screen_w=1920, screen_h=1080,
|
||
platform="Win32",
|
||
locale="en-US",
|
||
),
|
||
"blend_windows_chrome_laptop": Persona(
|
||
key="blend_windows_chrome_laptop",
|
||
user_agent=(
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||
"(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
||
),
|
||
accept_language="en-US,en;q=0.9",
|
||
timezone="America/Chicago",
|
||
screen_w=1366, screen_h=768,
|
||
platform="Win32",
|
||
locale="en-US",
|
||
),
|
||
"blend_windows_firefox": Persona(
|
||
key="blend_windows_firefox",
|
||
user_agent=(
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) "
|
||
"Gecko/20100101 Firefox/128.0"
|
||
),
|
||
accept_language="en-US,en;q=0.5",
|
||
timezone="America/New_York",
|
||
screen_w=1920, screen_h=1080,
|
||
platform="Win32",
|
||
locale="en-US",
|
||
),
|
||
"blend_windows_edge": Persona(
|
||
key="blend_windows_edge",
|
||
user_agent=(
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||
"(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0"
|
||
),
|
||
accept_language="en-US,en;q=0.9",
|
||
timezone="America/Chicago",
|
||
screen_w=1920, screen_h=1080,
|
||
platform="Win32",
|
||
locale="en-US",
|
||
),
|
||
"blend_mac_safari": Persona(
|
||
key="blend_mac_safari",
|
||
user_agent=(
|
||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
|
||
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15"
|
||
),
|
||
accept_language="en-US,en;q=0.9",
|
||
timezone="America/Los_Angeles",
|
||
screen_w=1680, screen_h=1050,
|
||
platform="MacIntel",
|
||
locale="en-US",
|
||
),
|
||
"blend_mac_chrome": Persona(
|
||
key="blend_mac_chrome",
|
||
user_agent=(
|
||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
|
||
"(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
||
),
|
||
accept_language="en-US,en;q=0.9",
|
||
timezone="America/Los_Angeles",
|
||
screen_w=1440, screen_h=900,
|
||
platform="MacIntel",
|
||
locale="en-US",
|
||
),
|
||
"blend_linux_firefox": Persona(
|
||
key="blend_linux_firefox",
|
||
user_agent=(
|
||
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:128.0) "
|
||
"Gecko/20100101 Firefox/128.0"
|
||
),
|
||
accept_language="en-US,en;q=0.5",
|
||
timezone="America/New_York",
|
||
screen_w=1920, screen_h=1080,
|
||
platform="Linux x86_64",
|
||
locale="en-US",
|
||
),
|
||
}
|
||
|
||
|
||
# ── Cookie policies ───────────────────────────────────────────────────────────
|
||
|
||
@dataclass(frozen=True)
|
||
class CookiePolicy:
|
||
"""
|
||
Complete Firefox cookie configuration expressed as a single composable unit.
|
||
|
||
behavior : network.cookie.cookieBehavior
|
||
0 = accept all
|
||
1 = block 3rd-party
|
||
2 = block ALL cookies
|
||
3 = block 3rd-party from unvisited sites
|
||
4 = block cross-site tracking (ETP Strict)
|
||
5 = block cross-site + social media trackers
|
||
lifetime : network.cookie.lifetimePolicy
|
||
0 = normal (respect Set-Cookie expires)
|
||
2 = session-only (all cookies expire on close)
|
||
partition : Total Cookie Protection — partition 3rd-party storage
|
||
by the top-level site (network.cookie.cookieBehavior.optInPartitioning)
|
||
clear_cookies : privacy.clearOnShutdown.cookies
|
||
clear_cache : privacy.clearOnShutdown.cache
|
||
clear_history : privacy.clearOnShutdown.history
|
||
clear_ls : privacy.clearOnShutdown.localStorage + indexedDB
|
||
clear_formdata : privacy.clearOnShutdown.formdata
|
||
sanitize : privacy.sanitize.sanitizeOnShutdown (master switch)
|
||
"""
|
||
behavior: int = 1
|
||
lifetime: int = 0
|
||
partition: bool = False
|
||
sanitize: bool = False
|
||
clear_cookies: bool = False
|
||
clear_cache: bool = False
|
||
clear_history: bool = False
|
||
clear_ls: bool = False
|
||
clear_formdata: bool = False
|
||
|
||
|
||
# Every cookie mode is a complete CookiePolicy — no guesswork in profile.py.
|
||
COOKIE_POLICIES: dict[str, CookiePolicy] = {
|
||
|
||
# ── Permissive ──────────────────────────────────────────────────────────
|
||
|
||
"accept_all": CookiePolicy(
|
||
behavior=0, lifetime=0,
|
||
# No clearing, no blocking — maximum site compatibility.
|
||
),
|
||
|
||
"accept_all_session": CookiePolicy(
|
||
behavior=0, lifetime=2,
|
||
sanitize=True, clear_cookies=True, clear_ls=True,
|
||
# Accept all cookies while browsing but wipe them when the
|
||
# browser closes. Good for signup / form-filling sessions.
|
||
),
|
||
|
||
# ── Standard 3rd-party blocking ────────────────────────────────────────
|
||
|
||
"block_third_party": CookiePolicy(
|
||
behavior=1, lifetime=0,
|
||
# Block 3rd-party, accept 1st-party with normal lifetime.
|
||
# Recommended baseline — most sites work fine.
|
||
),
|
||
|
||
"block_third_party_session": CookiePolicy(
|
||
behavior=1, lifetime=2,
|
||
sanitize=True, clear_cookies=True, clear_cache=True, clear_ls=True,
|
||
# Block 3rd-party AND treat all accepted cookies as session-only.
|
||
# Nothing persists. Use for anonymous sessions.
|
||
),
|
||
|
||
# ── Tracker-focused blocking ────────────────────────────────────────────
|
||
|
||
"block_third_party_trackers": CookiePolicy(
|
||
behavior=4, lifetime=0,
|
||
# Firefox ETP Strict mode: only blocks known trackers, not ALL
|
||
# 3rd-party cookies. Best blend-in option — same as Firefox default.
|
||
),
|
||
|
||
"block_social_trackers": CookiePolicy(
|
||
behavior=5, lifetime=0,
|
||
# Block cross-site cookies AND social-media tracking cookies
|
||
# (Facebook, Twitter pixels, etc.). Stricter than ETP Strict but
|
||
# still allows most logins.
|
||
),
|
||
|
||
"block_unvisited": CookiePolicy(
|
||
behavior=3, lifetime=0,
|
||
# Block 3rd-party from sites the user has never visited. Very light
|
||
# — almost invisible to sites; good when you need max compatibility.
|
||
),
|
||
|
||
# ── Partitioned storage (Total Cookie Protection) ───────────────────────
|
||
|
||
"partitioned_tcp": CookiePolicy(
|
||
behavior=1, lifetime=0, partition=True,
|
||
# Block 3rd-party AND enable Total Cookie Protection: each site
|
||
# gets its own isolated cookie jar so cross-site tracking via
|
||
# cookie sync is impossible. Recommended for blend-in + privacy.
|
||
),
|
||
|
||
"partitioned_session": CookiePolicy(
|
||
behavior=1, lifetime=2, partition=True,
|
||
sanitize=True, clear_cookies=True, clear_cache=True,
|
||
clear_ls=True, clear_formdata=True,
|
||
# Partitioned + session-only + full wipe on close. Leaves no
|
||
# persistent state on disk after the browser exits.
|
||
),
|
||
|
||
# ── Maximum wipe ───────────────────────────────────────────────────────
|
||
|
||
"session_only": CookiePolicy(
|
||
behavior=0, lifetime=2,
|
||
sanitize=True, clear_cookies=True,
|
||
# All cookies accepted but expire when the browser closes.
|
||
# Note: localStorage is NOT cleared here — only cookies.
|
||
),
|
||
|
||
"ghost_mode": CookiePolicy(
|
||
behavior=1, lifetime=2,
|
||
sanitize=True, clear_cookies=True, clear_cache=True,
|
||
clear_history=True, clear_ls=True, clear_formdata=True,
|
||
partition=True,
|
||
# Maximum ephemeral session: block 3rd-party, TCP partitioning,
|
||
# session-only lifetime, full wipe of cookies + cache + history +
|
||
# localStorage/IndexedDB + formdata on every close. Zero disk trace.
|
||
),
|
||
|
||
"block_all": CookiePolicy(
|
||
behavior=2, lifetime=0,
|
||
# Block ALL cookies. Most login-dependent sites will break.
|
||
# Only useful for read-only scraping sessions.
|
||
),
|
||
}
|
||
|
||
COOKIE_MODES: list[str] = list(COOKIE_POLICIES)
|
||
|
||
COOKIE_LABELS: dict[str, str] = {
|
||
"accept_all": "Accept all — maximum compatibility (cookies persist)",
|
||
"accept_all_session": "Accept all, session only — wipe cookies on close",
|
||
"block_third_party": "Block 3rd-party — recommended baseline (persists 1st-party)",
|
||
"block_third_party_session": "Block 3rd-party + session — nothing persists",
|
||
"block_third_party_trackers":"Block trackers only — ETP Strict (Firefox default-strict)",
|
||
"block_social_trackers": "Block social + cross-site trackers (Facebook pixel, etc.)",
|
||
"block_unvisited": "Block 3rd-party from unvisited sites — lightest option",
|
||
"partitioned_tcp": "Partitioned (TCP) — each site gets isolated 3rd-party jar",
|
||
"partitioned_session": "Partitioned + session — isolated jars, full wipe on close",
|
||
"session_only": "Session only — all cookies expire on close (no partition)",
|
||
"ghost_mode": "Ghost mode — partitioned + session + full disk wipe on close",
|
||
"block_all": "Block ALL cookies — breaks most logins",
|
||
}
|
||
|
||
|
||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||
|
||
def get_cookie_policy(mode: str) -> CookiePolicy:
|
||
return COOKIE_POLICIES.get(mode, COOKIE_POLICIES["block_third_party"])
|
||
|
||
|
||
# Legacy shims kept for code that still calls these directly.
|
||
def cookie_behavior_value(mode: str) -> int:
|
||
return get_cookie_policy(mode).behavior
|
||
|
||
|
||
def cookie_session_only(mode: str) -> bool:
|
||
return get_cookie_policy(mode).lifetime == 2
|
||
|
||
|
||
def get_persona(key: str) -> Persona | None:
|
||
return PERSONA_DATA.get(key)
|
||
|
||
|
||
def is_blend_persona(key: str) -> bool:
|
||
return key.startswith("blend_")
|