Build comprehensive privacy suite and hardened browser controls.
Adds VPN-aware leak handling, chain testing UX improvements, hardened Firefox launch/profile management, privacy/device hardening modules, and tray/status upgrades so the app is production-ready as the new baseline. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
55
proxy_chain_manager/leak_detect.py
Normal file
55
proxy_chain_manager/leak_detect.py
Normal file
@@ -0,0 +1,55 @@
|
||||
"""VPN-aware chain leak detection."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def is_same_subnet(ip_a: str | None, ip_b: str | None, prefix_len: int = 16) -> bool:
|
||||
"""True if two IPv4 addresses share the same /prefix_len subnet."""
|
||||
if not ip_a or not ip_b:
|
||||
return False
|
||||
try:
|
||||
a_parts = [int(x) for x in ip_a.split(".")]
|
||||
b_parts = [int(x) for x in ip_b.split(".")]
|
||||
if len(a_parts) != 4 or len(b_parts) != 4:
|
||||
return False
|
||||
|
||||
def to_int(parts: list[int]) -> int:
|
||||
return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]
|
||||
|
||||
mask = (0xFFFFFFFF << (32 - prefix_len)) & 0xFFFFFFFF
|
||||
return (to_int(a_parts) & mask) == (to_int(b_parts) & mask)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def is_chain_leak(exit_ip: str | None, real_ip: str | None, vpn_active: bool) -> bool:
|
||||
"""True when the chain is not forwarding (traffic still looks like direct/VPN exit).
|
||||
|
||||
With VPN: compare /16 — VPN IPs rotate but stay in-provider ranges.
|
||||
Without VPN: exact IP match only (avoid false positives on same ISP /16).
|
||||
"""
|
||||
if not exit_ip:
|
||||
return True
|
||||
if not real_ip:
|
||||
return False
|
||||
if exit_ip == real_ip:
|
||||
return True
|
||||
if vpn_active:
|
||||
return is_same_subnet(exit_ip, real_ip)
|
||||
return False
|
||||
|
||||
|
||||
def leak_reason(exit_ip: str | None, real_ip: str | None, vpn_active: bool) -> str:
|
||||
if not exit_ip:
|
||||
return "exit IP unreachable"
|
||||
if not real_ip:
|
||||
return "unknown direct IP"
|
||||
if exit_ip == real_ip:
|
||||
if vpn_active:
|
||||
return f"exit {exit_ip} equals VPN/direct IP (chain not forwarding)"
|
||||
return f"exit {exit_ip} equals your real IP (no anonymization)"
|
||||
if vpn_active and is_same_subnet(exit_ip, real_ip):
|
||||
return (
|
||||
f"exit {exit_ip} shares /16 with direct {real_ip} "
|
||||
"(likely exiting via VPN tunnel, not proxy chain)"
|
||||
)
|
||||
return "ok"
|
||||
Reference in New Issue
Block a user