fix: audit round 3 - fail-closed leak, shared asyncio loop, GOST bundling, close-X UX, persona key lookup, +29 tests
This commit is contained in:
@@ -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)"
|
||||
|
||||
Reference in New Issue
Block a user