fix: audit round 2 - DPAPI secrets, pinned hop probe, gost exe hash, admin guard, PID-scoped browser tracking, emergency disengage button, build sidecar
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:07:07 -07:00
parent 04d486a335
commit ad56f75e8a
12 changed files with 502 additions and 104 deletions

View File

@@ -161,66 +161,10 @@ def _dns_resolve_via_system(hostname: str, timeout: float = 5.0) -> str | None:
return None
@dataclass(frozen=True)
class DnsLeakResult:
resolver: str
ip_via_proxy: str | None
ip_direct: str | None
leaked: bool
detail: str
def check_dns_leak(
proxy_url: str,
timeout_seconds: float = 8.0,
) -> list[DnsLeakResult]:
"""
Detect DNS leaks: compare hostname resolution seen through proxy vs direct.
A mismatch means DNS is escaping the tunnel.
"""
test_hosts = [
("Cloudflare (1.1.1.1)", "one.one.one.one"),
("Google (8.8.8.8)", "dns.google"),
("OpenDNS", "resolver1.opendns.com"),
]
results: list[DnsLeakResult] = []
timeout = httpx.Timeout(timeout_seconds, connect=min(6.0, timeout_seconds))
for label, host in test_hosts:
# Get IP via direct system DNS
direct_ip = _dns_resolve_via_system(host)
# Get IP as seen from the proxy path (via http://dns-endpoint)
proxy_ip: str | None = None
try:
with httpx.Client(proxy=proxy_url, timeout=timeout, verify=False, follow_redirects=True) as c:
r = c.get(f"https://{host}/")
proxy_ip = str(r.headers.get("x-real-ip") or "")
if not proxy_ip:
# fall back: grab connected IP from response
proxy_ip = None
except Exception:
pass
# Simple leak heuristic: if direct resolution works but proxy connection fails, possible leak path
leaked = bool(direct_ip and not proxy_ip)
if leaked:
detail = f"DNS resolved directly to {direct_ip} but proxy could not reach it — possible bypass"
elif not direct_ip:
detail = "Could not resolve directly"
leaked = False
else:
detail = f"Direct: {direct_ip}"
results.append(DnsLeakResult(
resolver=label,
ip_via_proxy=proxy_ip,
ip_direct=direct_ip,
leaked=leaked,
detail=detail,
))
return results
# NOTE: removed legacy ``check_dns_leak`` / ``DnsLeakResult`` — they relied on
# the ``x-real-ip`` HTTP response header which proxy targets do not set, so
# results were meaningless. Use :func:`proxy_chain_manager.dns_leak.run_dns_leak_test`
# instead.
def run_ban_tests(