fix: audit round 3 - fail-closed leak, shared asyncio loop, GOST bundling, close-X UX, persona key lookup, +29 tests
Some checks failed
CI / Test Python 3.10 (push) Has been cancelled
CI / Test Python 3.11 (push) Has been cancelled
CI / Test Python 3.12 (push) Has been cancelled

This commit is contained in:
Dr Jones
2026-05-22 18:23:52 -07:00
parent ad56f75e8a
commit b852fd264f
15 changed files with 556 additions and 19 deletions

View File

@@ -26,11 +26,17 @@ def is_chain_leak(exit_ip: str | None, real_ip: str | None, vpn_active: bool) ->
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).
**Fail-closed**: when ``real_ip`` is unknown we cannot prove the chain is
safe, so we conservatively return ``True``. The service loop applies a
short warm-up grace period before this verdict kicks in so a transient
direct-IP lookup failure doesn't cause perpetual rotation.
"""
if not exit_ip:
return True
if not real_ip:
return False
# Fail-closed: README promises "fail closed" when trust dies.
return True
if exit_ip == real_ip:
return True
if vpn_active:
@@ -42,7 +48,10 @@ def leak_reason(exit_ip: str | None, real_ip: str | None, vpn_active: bool) -> s
if not exit_ip:
return "exit IP unreachable"
if not real_ip:
return "unknown direct IP"
return (
"direct IP unknown — cannot prove the chain is forwarding "
"(fail-closed). Check internet connectivity and ip_check_url."
)
if exit_ip == real_ip:
if vpn_active:
return f"exit {exit_ip} equals VPN/direct IP (chain not forwarding)"