Spoof-when-possible browser personas, Tier-2 telemetry kill + artifact wipe, UI polish

Browser: identity persona dropdown (blend Windows-Chrome / Firefox / mac-Safari / hardened / custom) + cookie policy dropdown. Blend personas relax RFP/FPI/strict-TP so the machine looks normal while still hiding behind the chain. Persona TZ applied via env var; UA / language / locale / screen via user.js. WebRTC still forced off (it leaks real IP). Privacy: Telemetry kill toggle (DiagTrack, Activity History, ad ID, Cortana, scheduled tasks) with full snapshot/restore. One-button forensic artifact wipe (TEMP, Recent, Jump Lists, Prefetch, MRU, clipboard). UI: neon palette, glow card borders, gradient header banner.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Indiana Holmes
2026-05-16 23:07:18 -07:00
parent 6561bdc37f
commit 094e0577fb
9 changed files with 1050 additions and 24 deletions

View File

@@ -35,6 +35,13 @@ from .firewall import (
is_engaged as fw_is_engaged,
request_admin_relaunch,
)
from .artifact_wipe import wipe_artifacts
from .browser_identity import (
COOKIE_LABELS,
COOKIE_MODES,
PERSONA_LABELS,
PERSONAS,
)
from .dns_leak import check_dns_leak_hint, flush_dns_cache
from .leak_audit import AuditReport, run_audit_sync
from .browser_launcher import (
@@ -80,22 +87,26 @@ class UILogHandler(logging.Handler):
# ── palette ──────────────────────────────────────────────────────────────────
BG = "#0d0d1a"
CARD = "#12122a"
PANEL = "#1a1a3e"
ACCENT = "#1e3a8a"
ACCENT2 = "#2563eb"
GREEN = "#00e676"
RED = "#ff1744"
YELLOW = "#ffab00"
ORANGE = "#ff6d00"
PURPLE = "#bb86fc"
BLUE = "#448aff"
CYAN = "#00bcd4"
DIM = "#4a5568"
TEXT = "#e2e8f0"
TEXT2 = "#94a3b8"
FONT = "Segoe UI"
# Neon "blueprint terminal" theme — same overall vibe, deeper black, sharper
# cyan/magenta accent, glow borders rendered via 1px border_color on cards.
BG = "#070713"
CARD = "#0f0f24"
PANEL = "#171738"
ACCENT = "#3052ff" # primary action / outlines
ACCENT2 = "#00e5ff" # secondary highlight / glow
GREEN = "#00ff9c"
RED = "#ff2a6d"
YELLOW = "#ffd000"
ORANGE = "#ff8a00"
PURPLE = "#c77dff"
BLUE = "#5b8bff"
CYAN = "#00f5ff"
MAGENTA = "#ff00d6"
DIM = "#2a2f4a"
TEXT = "#eaf2ff"
TEXT2 = "#7a8aab"
GLOW = "#0a87ff"
FONT = "Segoe UI"
def _ts() -> str:
@@ -108,10 +119,56 @@ def main() -> None:
root = ctk.CTk()
root.title("Proxy God v2")
root.geometry("1080x740")
root.geometry("1080x760")
root.minsize(900, 620)
root.configure(fg_color=BG)
# ── 3D-ish neon header banner (drawn on a Canvas for a true gradient) ────
def _draw_header_banner(parent: Any) -> Any:
import tkinter as tk
canvas = tk.Canvas(
parent, height=44, highlightthickness=0, bd=0, bg=BG,
)
canvas.pack(fill="x", side="top")
def _hex(rgb: tuple[int, int, int]) -> str:
return "#" + "".join(f"{v:02x}" for v in rgb)
def _lerp(a: tuple[int, int, int], b: tuple[int, int, int], t: float) -> tuple[int, int, int]:
return tuple(int(a[i] + (b[i] - a[i]) * t) for i in range(3)) # type: ignore[return-value]
def _repaint(_event: Any = None) -> None:
canvas.delete("grad")
w = canvas.winfo_width() or 1080
h = 44
left = (8, 32, 64) # near-black blue
mid = (48, 82, 255) # ACCENT
right = (0, 229, 255) # ACCENT2 cyan
for x in range(0, w, 2):
t = x / max(1, w - 1)
c = _lerp(left, mid, t * 2) if t < 0.5 else _lerp(mid, right, (t - 0.5) * 2)
canvas.create_line(x, 0, x, h, fill=_hex(c), tags="grad")
# 1px neon underline
canvas.create_line(0, h - 1, w, h - 1, fill=CYAN, width=1, tags="grad")
# Title text + small subtitle
canvas.create_text(
18, h // 2 - 2, anchor="w",
text="P R O X Y G O D",
fill="#ffffff", font=(FONT, 16, "bold"),
tags="grad",
)
canvas.create_text(
190, h // 2 - 1, anchor="w",
text="// multi-hop · anti-fingerprint · paranoid mode",
fill="#bfeaff", font=(FONT, 9, "italic"),
tags="grad",
)
canvas.bind("<Configure>", _repaint)
return canvas
_draw_header_banner(root)
ui_q: queue.Queue[dict[str, Any]] = queue.Queue()
svc = ChainService(notify=lambda m: ui_q.put(m))
s = load_settings()
@@ -847,7 +904,10 @@ def main() -> None:
ctk.CTkLabel(
br_scroll, text=subtitle, font=(FONT, 10), text_color=TEXT2, wraplength=900, justify="left"
).pack(anchor="w", padx=8, pady=(0, 4))
f = ctk.CTkFrame(br_scroll, fg_color=CARD, corner_radius=8)
f = ctk.CTkFrame(
br_scroll, fg_color=CARD, corner_radius=10,
border_width=1, border_color=GLOW,
)
f.pack(fill="x", padx=8, pady=(4, 8))
return f
@@ -895,6 +955,78 @@ def main() -> None:
"Browser controls",
"These settings are applied each time you launch from this tab.",
)
persona_card = _section_inline(
br_scroll,
"Identity persona (spoof when possible, block when not)",
"Blend-in personas mimic the most common Windows + Chrome setup so the "
"browser looks normal. Hardened mode is the classic 'block everything' "
"profile but stands out as anti-fingerprint.",
) if "_section_inline" in dir() else None
if persona_card is None:
persona_card = ctk.CTkFrame(
br_scroll, fg_color=CARD, corner_radius=10,
border_width=1, border_color=GLOW,
)
persona_card.pack(fill="x", padx=8, pady=(2, 8))
ctk.CTkLabel(
persona_card,
text="Identity persona (spoof when possible, block when not)",
font=(FONT, 12, "bold"),
text_color=ORANGE,
).pack(anchor="w", padx=12, pady=(10, 0))
ctk.CTkLabel(
persona_card,
text=(
"Blend-in personas mimic the most common Windows + Chrome setup "
"so the browser looks normal. Hardened = full anti-fingerprint."
),
font=(FONT, 9), text_color=TEXT2, justify="left", wraplength=820,
).pack(anchor="w", padx=12, pady=(0, 6))
persona_row = ctk.CTkFrame(persona_card, fg_color="transparent")
persona_row.pack(fill="x", padx=12, pady=(0, 6))
ctk.CTkLabel(persona_row, text="Persona:", font=(FONT, 11), text_color=TEXT,
width=80, anchor="w").pack(side="left")
persona_var = ctk.StringVar(
value=PERSONA_LABELS.get(s.browser_persona, PERSONA_LABELS["blend_windows_chrome"])
)
persona_menu = ctk.CTkOptionMenu(
persona_row,
values=[PERSONA_LABELS[k] for k in PERSONAS],
variable=persona_var,
fg_color=BG, button_color=ACCENT2, button_hover_color=ACCENT,
text_color=TEXT, font=(FONT, 11), width=500,
)
persona_menu.pack(side="left", padx=(4, 0))
cookie_row = ctk.CTkFrame(persona_card, fg_color="transparent")
cookie_row.pack(fill="x", padx=12, pady=(0, 10))
ctk.CTkLabel(cookie_row, text="Cookies:", font=(FONT, 11), text_color=TEXT,
width=80, anchor="w").pack(side="left")
cookie_var = ctk.StringVar(
value=COOKIE_LABELS.get(s.browser_cookie_mode, COOKIE_LABELS["block_third_party"])
)
cookie_menu = ctk.CTkOptionMenu(
cookie_row,
values=[COOKIE_LABELS[k] for k in COOKIE_MODES],
variable=cookie_var,
fg_color=BG, button_color=ACCENT2, button_hover_color=ACCENT,
text_color=TEXT, font=(FONT, 11), width=500,
)
cookie_menu.pack(side="left", padx=(4, 0))
def _persona_key() -> str:
for k in PERSONAS:
if PERSONA_LABELS[k] == persona_var.get():
return k
return "blend_windows_chrome"
def _cookie_key() -> str:
for k in COOKIE_MODES:
if COOKIE_LABELS[k] == cookie_var.get():
return k
return "block_third_party"
br_force_proxy_var = ctk.BooleanVar(value=s.browser_force_proxy)
br_disable_webrtc_var = ctk.BooleanVar(value=s.browser_disable_webrtc)
br_rfp_var = ctk.BooleanVar(value=s.browser_resist_fingerprinting)
@@ -984,6 +1116,8 @@ def main() -> None:
first_party_isolation=bool(br_fpi_var.get()),
strict_tracking_protection=bool(br_strict_tp_var.get()),
timezone_utc=bool(br_tz_utc_var.get()),
persona=_persona_key(),
cookie_mode=_cookie_key(),
)
def _refresh_browser_status() -> None:
@@ -1043,7 +1177,10 @@ def main() -> None:
ctk.CTkLabel(priv_scroll, text=subtitle, font=(FONT, 10),
text_color=TEXT2, wraplength=900, justify="left").pack(
anchor="w", padx=8, pady=(0, 4))
f = ctk.CTkFrame(priv_scroll, fg_color=CARD, corner_radius=8)
f = ctk.CTkFrame(
priv_scroll, fg_color=CARD, corner_radius=10,
border_width=1, border_color=GLOW,
)
f.pack(fill="x", padx=8, pady=(4, 8))
return f
@@ -1090,6 +1227,7 @@ def main() -> None:
ipv6_var = ctk.BooleanVar(value=s.disable_ipv6_while_active)
webrtc_var = ctk.BooleanVar(value=s.harden_webrtc_enabled)
lan_var = ctk.BooleanVar(value=s.lan_lockdown_enabled)
telemetry_var = ctk.BooleanVar(value=s.telemetry_kill_enabled)
def _priv_toggle(parent: Any, text: str, var: ctk.BooleanVar, tip: str = "") -> ctk.CTkCheckBox:
cb = ctk.CTkCheckBox(
@@ -1132,6 +1270,13 @@ def main() -> None:
"Stops your machine from advertising its hostname on the local network "
"(admin required, reversible on stop).",
)
_priv_toggle(
toggles_card,
"Telemetry kill: DiagTrack, Activity History, Cortana web, ad ID",
telemetry_var,
"Stops Windows telemetry pipelines while chain is up. Reversible on stop "
"(snapshot of original state taken).",
)
fp_card = _priv_section(
"Device fingerprint",
@@ -1177,6 +1322,35 @@ def main() -> None:
_btn(dns_btn_row, "Flush DNS now", _manual_dns_flush, w=110, h=28,
fg_color=DIM).pack(side="left")
wipe_card = _priv_section(
"Forensic artifact wipe",
"One-button purge of common Windows breadcrumb trails. Irreversible.",
)
wipe_result_lbl = ctk.CTkLabel(
wipe_card, text="Click 'Wipe now' to purge %TEMP%, Recent, Jump Lists, "
"Prefetch (Admin), MRU lists, and the clipboard.",
font=(FONT, 10), text_color=TEXT2, wraplength=880, justify="left",
)
wipe_result_lbl.pack(anchor="w", padx=12, pady=8)
def _do_wipe() -> None:
wipe_result_lbl.configure(text="Wiping…", text_color=YELLOW)
def work() -> None:
try:
rep = wipe_artifacts(include_prefetch=True)
except Exception as e:
root.after(0, lambda: wipe_result_lbl.configure(
text=f"Wipe failed: {e}", text_color=RED))
return
root.after(0, lambda: wipe_result_lbl.configure(
text=rep.summary(), text_color=GREEN if not rep.errors else YELLOW))
threading.Thread(target=work, daemon=True).start()
_btn(wipe_card, "Wipe now", _do_wipe, w=110, h=28,
fg_color=RED, hover_color="#8a1d1d").pack(anchor="w", padx=12, pady=(0, 10))
audit_card = _priv_section(
"Leak audit (mission-critical)",
"Probes every leak surface: IP, DNS, IPv6, WPAD, Group Policy, "
@@ -1310,6 +1484,9 @@ def main() -> None:
ipv6_var.set(False)
webrtc_var.set(True)
lan_var.set(False)
telemetry_var.set(False)
persona_var.set(PERSONA_LABELS["blend_windows_chrome"])
cookie_var.set(COOKIE_LABELS["block_third_party"])
br_force_proxy_var.set(True)
br_disable_webrtc_var.set(True)
br_rfp_var.set(True)
@@ -1381,6 +1558,7 @@ def main() -> None:
disable_ipv6_while_active=bool(ipv6_var.get()),
harden_webrtc_enabled=bool(webrtc_var.get()),
lan_lockdown_enabled=bool(lan_var.get()),
telemetry_kill_enabled=bool(telemetry_var.get()),
firefox_path=firefox_path_var.get().strip(),
firefox_profile_dir=firefox_profile_var.get().strip(),
browser_clear_on_close=bool(br_clear_var.get()),
@@ -1395,6 +1573,8 @@ def main() -> None:
browser_first_party_isolation=bool(br_fpi_var.get()),
browser_strict_tracking_protection=bool(br_strict_tp_var.get()),
browser_timezone_utc=bool(br_tz_utc_var.get()),
browser_persona=_persona_key(),
browser_cookie_mode=_cookie_key(),
)
if not (1 <= ns.local_port <= 65535):
raise ValueError("Port must be 1-65535")