Files
proxy-god/docs/AUDIT_FINDINGS.md
Dr Jones ad56f75e8a
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
fix: audit round 2 - DPAPI secrets, pinned hop probe, gost exe hash, admin guard, PID-scoped browser tracking, emergency disengage button, build sidecar
2026-05-22 18:07:07 -07:00

18 KiB
Raw Blame History

Proxy God — Audit Findings

Generated: 2026-05-22
Tests: 47/47 pass · compileall clean
Severity summary: P0: 12 · P1: 28 · P2: 22 · Total: 62


Executive Summary

Severity Count
Critical (P0) 12
High (P1) 28
Medium (P2) 22
Total 62

Already remediated (prior passes): CI workflow, GOST SHA256 pin, kill-switch emergency_disengage + atexit, settings migration/backup, log rotation, MIT LICENSE, GOST SHA256 verified correct.


Top P0 Issues

  1. Wrong Chrome/Edge WebRTC policy key/valuefingerprint.py:21,177 writes DWORD 2 which is default_public_and_private_interfaces, NOT disable_non_proxied_udp (DWORD 3). Modern Chrome also requires REG_SZ WebRtcIPHandling = disable_non_proxied_udp. Audits treat 2 as success → false green.
  2. BrowserSession.stop() kills ALL Firefox on the machinebrowser_launcher.py:297-305 runs taskkill /F /IM firefox.exe with no PID scope. Operator loses unrelated browser sessions.
  3. Credentials plaintext at restconfig.py:19-22, signup_prep.py:252-325 store proxy auth + signup passwords in JSON. cryptography==48.0.0 is in requirements but unused.
  4. Preflight race conditionapp.py:2001-2009 uses fixed root.after(200, _final) which can report "All passed" before async network checks finish.
  5. Preflight IP compare is exact-match only — ignores the VPN-aware /16 logic used in production leak detection (leak_detect.py:24-38).
  6. HTTPS CONNECT failure doesn't stop chainservice.py:573-580 logs warning only; chain stays "healthy" and system proxy remains set.
  7. Pinned manual chain never validates hops at runtime — dead chain retries every 10s forever (service.py:393-403).
  8. emergency_disengage() runs on ALL exits — even if kill-switch never engaged; can mask other apps' firewall state (service.py:105, firewall.py:165-177).
  9. Signup extension runs on all URLssignup_extension/manifest.json:13-19 uses <all_urls>.
  10. Account auto-saved before signup completes — password saved on browser launch before user registers (app.py:2147-2174).
  11. GOST exe not re-hashed on reuse — zip is verified but extracted gost.exe on disk is not re-checked (gost_util.py:61-64).
  12. asyncio.run() from worker threadsapp.py:1860-1863 nested event loop risk if caller context changes.

1. Critical Bugs

ID Finding File:Line
C-01 WebRTC policy wrong key/type/value fingerprint.py:18-21,162-177, webrtc_check.py:37-96, leak_audit.py:138-157
C-02 Browser stop kills all firefox.exe globally browser_launcher.py:297-305
C-03 Plaintext settings.json / signup JSON credentials config.py:19-22, signup_prep.py:252-325
C-04 Preflight root.after(200) race — final verdict before checks complete app.py:2001-2009
C-05 Preflight IP compare exact-match only (ignores /16 VPN logic) app.py:1886-1893, leak_detect.py:24-38
C-06 HTTPS CONNECT failure keeps chain "healthy" service.py:573-580
C-07 Pinned chain never validates hops at runtime service.py:393-403
C-08 emergency_disengage() fires on ALL exits service.py:105, firewall.py:165-177
C-09 Signup extension <all_urls> permissions signup_extension/manifest.json:13-19
C-10 Account saved before signup completes app.py:2147-2174
C-11 GOST exe not re-hashed on disk reuse gost_util.py:61-64
C-12 asyncio.run() from worker threads app.py:1860-1863

2. Edge Cases / Failure Modes

ID Finding File:Line
E-01 real_ip captured once at start; VPN reconnect mid-session not reflected service.py:339-340,551-558
E-02 Sticky exit suppresses leak rotation but not manual rotate/GOST death service.py:607-619
E-03 Sticky + health leak: status forced "healthy" while leaking service.py:610-618
E-04 is_chain_leak(real_ip=None) returns False (no leak) — fail-open leak_detect.py:32-33
E-05 Same /16 ISP neighbors never flagged — some leak modes missed by design leak_detect.py:36-37
E-06 Empty pinned chain + use_pinned_chain=True falls through to pool silently service.py:393, config.py:201
E-07 chain_length=1 + manual exit only — no mid-hop redundancy service.py:407-415
E-08 Obfuscation random_mix shuffles list but takes prefix slice — not random per hop service.py:641-644,717
E-09 Pool exhausted → reshuffle; blacklisted proxies stay excluded until refresh service.py:409-417,768-771
E-10 Fixed exit validation failure still used in chains service.py:822-839
E-11 socket.setdefaulttimeout() global mutation — thread race in DNS helpers dns_leak.py:140-151, ban_tester.py:149-150
E-12 DNS leak "proxy path" uses Google DoH through HTTP proxy — not equivalent to system DNS dns_leak.py:154-167
E-13 DNS all_match logic can false-flag or miss due to CDN/geo DNS answers dns_leak.py:221-252
E-14 Kill-switch allows outbound DNS globally — DNS exfil channel exists firewall.py:136-140
E-15 Kill-switch skipped when non-admin with only log line service.py:350-357
E-16 IPv6 disable skips virtual adapters by name heuristics only fingerprint.py:122-137
E-17 Hostname rename may require reboot; partial apply possible fingerprint.py:73-103
E-18 MAC spoof restore depends on in-memory originals — crash mid-session may leave spoofed MAC service.py:96-97
E-19 BrowserSession.is_running() treats any firefox.exe within 5 min as "ours" browser_launcher.py:153-157
E-20 Auto-relaunch can loop if profile locked/corrupt app.py:2866-2871
E-21 task_exists() logon task runs LIMITED — no admin kill-switch at boot windows_task.py:47-48
E-22 Group Policy proxy locks detected but never remediated sysproxy.py:298-317, service.py:586-594
E-23 load_settings auto-rewrites sanitized file — can surprise operators config.py:436-443
E-24 _is_safe_https_url allows http:// sources — MITM on pool fetch config.py:266-271, fetcher.py:13-16
E-25 Ban tester DNS leak helper checks x-real-ip header (usually absent) — nonsense results ban_tester.py:169-219
E-26 Ban tester _looks_banned_body matches "captcha" on normal pages → false bans ban_tester.py:71-89,133-134
E-27 run_ban_tests(categories=["All"]) duplicates sites ban_tester.py:237-243
E-28 Exit intel/geo fetch via third-party APIs through proxy — telemetry surface exit_intel.py, chain_map.py:152-179
E-29 World map geo resolution uses direct socket.getaddrinfo — DNS leak for hop lookup chain_map.py:86-112,160
E-30 GOST immediate exit blacklists hops but pinned/manual exit exempt service.py:515-522,557-562

3. Missing Features / README Gaps

ID Finding Reference
M-01 README "self-healing forever" — pinned mode doesn't rotate pool README.md:9, service.py:393-403
M-02 README "fail closed" — non-admin + kill-switch skipped README.md:25, service.py:350-357
M-03 README 18 hops; UI/config says 28 in places README.md:48, config.py:167
M-04 No in-GUI emergency kill-switch disengage button firewall.py, app.py
M-05 audit_device() is OS-only but UI shows it under "Browser Fingerprint" fingerprint.py:299-383, app.py:2310-2313
M-06 Preflight card mentions "fingerprint" but no fingerprint check in _PF_CHECKS app.py:1775-1793
M-07 browser_auto_relaunch not tied to chain health flag app.py:2866-2871, config.py:205
M-08 No export/import encrypted settings/signup vault
M-09 No persisted ban-test / audit history app.py
M-10 prefer_elite can empty pool with no GUI recovery wizard config.py:183, service.py:754-761
M-11 SOCKS5 remote DNS disabled in Firefox profile browser_profile.py:125
M-12 Signup presets have no ToS/disclaimer in UI signup_prep.py:37-160
M-13 No IPv6 chain path — IPv6 disable adapter-level only fingerprint.py:106-138
M-14 Tray red/yellow/green with no click-through to failed check detail tray.py, app.py:2841-2844
M-15 CHANGELOG.md claims DPAPI/Fernet — not implemented CHANGELOG.md:35-36

4. Build / Packaging / Deployment

ID Finding Reference
B-01 No Authenticode signing ProxyChainManager.spec:70-71
B-02 UPX enabled — AV false positives risk ProxyChainManager.spec:66-67
B-03 uac_admin=True — every launch elevates ProxyChainManager.spec:72
B-04 PyInstaller not pinned in requirements.txt scripts/setup_and_build.ps1:39
B-05 Build script doesn't emit SHA256 sidecar scripts/setup_and_build.ps1:50-58
B-06 GOST not bundled — first run requires GitHub access gost_util.py:61-86
B-07 __version__ static 1.0.0, not tied to git tag __init__.py:3
B-08 CI does not run PyInstaller build .github/workflows/test.yml
B-09 No SBOM / pip freeze in release artifacts
B-10 Defender exclusion adds whole %LOCALAPPDATA%\ProxyChainManager folder gost_util.py:29-45

5. Security / Privacy

ID Finding Reference
S-01 Plaintext secrets at rest (proxy creds + signup passwords) config.py, signup_prep.py
S-02 WebRTC mis-hardening (wrong policy value) fingerprint.py
S-03 All httpx clients use verify=False — MITM risk validator.py:142, ban_tester.py:119, dns_leak.py:159
S-04 Signup passwords can appear in UI/log via clipboard actions app.py:2059-2062
S-05 Signup extension content script on all URLs signup_extension/manifest.json
S-06 Public proxy list sources — hostile infrastructure by design config.py:218-223
S-07 cryptography dependency unused — attack surface without benefit requirements.txt:5
S-08 Kill-switch + DNS allow rule = DNS bypass channel firewall.py:136-140
S-09 Forensic wipe deletes Recycle Bin without extra confirmation artifact_wipe.py:208-216
S-10 No secure deletion of signup JSON on uninstall

6. UI/UX Issues

ID Finding Reference
U-01 Window close minimizes to tray — chain/firewall active silently app.py:2908
U-02 "Run as Admin" relaunch closes app — unsaved UI state lost app.py:347-350
U-03 No version/build SHA in About UI __init__.py:3
U-04 Cookie/persona menus reverse-lookup by label — fragile if labels change app.py:1321-1325
U-05 Hardened toggles visible even when blend persona overrides them browser_profile.py:42-65
U-06 Preflight "fingerprint" in subtitle but not in checklist app.py:1775-1793
U-07 Ban tester has no progress bar for 30+ sites ban_tester.py:222-260
U-08 Saved accounts list shows email + password in plain text app.py:2046-2049
U-09 Chain map silently skips hops when geo lookup fails — no unknown marker chain_map.py:156-166,322-328
U-10 verbose_logs_var affects UI handler only; file log stays INFO app.py:707-713

7. Test Coverage Gaps

ID Finding
T-01 No tests for service.py (rotation, sticky, kill-switch)
T-02 No tests for firewall.py / emergency_disengage
T-03 No tests for sysproxy.py registry blob encoding
T-04 No tests for GOST SHA256 mismatch path
T-05 No tests for dns_leak.run_dns_leak_test verdict logic
T-06 No tests for webrtc_check / apply_webrtc_hardening
T-07 No tests for BrowserSession
T-08 No tests for signup_prep.install_signup_extension
T-09 No tests for config.load_settings/migrate/sanitize round-trip
T-10 No tests for ban_tester heuristics
T-11 No GUI/smoke tests for app.py (~2900 lines)
T-12 test_fetch_smoke is network-dependent — can skip silently in CI
T-13 No test that WebRTC policy value matches Chrome documentation
T-14 No frozen-bundle (_MEIPASS) path tests in CI

P0 — Fix immediately:
C-01, C-02, C-03, C-04, C-05, C-06, S-01, S-02, S-03, B-01

P1 — Next sprint:
C-07, C-10, E-01E-06, E-11, E-22, E-25E-27, M-04M-07, M-11, B-04B-06, T-01T-05, T-09, U-01U-03

P2 — Backlog:
All remaining E/M/B/U/T items, installer signing, metrics, coverage gates


9. Remediation log (2026-05-22 passes)

ID Status Notes
C-01 Fixed fingerprint.py, webrtc_check.py — DWORD 3 + WebRtcIPHandling REG_SZ
C-02 Fixed browser_launcher.py — scoped taskkill /PID
C-04 Fixed app.py_final scheduled after all after(0) callbacks
C-05 Fixed app.py preflight uses is_chain_leak() + VPN-aware /16
C-06 Fixed service.py — HTTPS CONNECT failure rotates chain (not healthy)
C-08 Fixed firewall.pyemergency_disengage() no-op unless is_engaged()
C-10 Fixed app.py — auto-save on launch is pending with empty password
E-06 Fixed service.py — log when pinned chain enabled but empty
E-11 Fixed dns_leak.py, ban_tester.py — restore socket timeout in finally
E-24 Fixed config.py — pool sources must be https:// only
E-26 Fixed ban_tester.py — removed bare "captcha" hint; stricter phrases
E-27 Fixed ban_tester.py — dedupe by URL
M-06 / U-06 Fixed Preflight subtitle no longer claims “fingerprint” check
M-15 Fixed CHANGELOG.md — Fernet/DPAPI not implemented (clarified)
B-02 Fixed ProxyChainManager.specupx=False
leak_audit Fixed _check_webrtc_policy() accepts DWORD 3 or REG_SZ
(prior) Fixed CI, GOST zip SHA256, settings migration/backup, LICENSE, log rotation

10. Still needs to be fixed

Items below were not changed because they need design decisions, external tooling (certs, infra), or behavior that is not safe to guess.

Critical / security (P0)

ID Why left open Suggested direction
C-09 Narrowing signup extension off <all_urls> breaks custom signup URLs the operator types in Dynamic host permissions API or per-session host approval prompt
C-12 asyncio.run() in worker threads (app.py preflight) needs a dedicated event-loop policy refactor Move all preflight network ops to a single asyncio runner thread
S-03 verify=False on httpx is intentional for the broken-cert reality of public proxies Per-setting toggle with security warning, documented trade-off
B-01 Authenticode signing needs an actual code-signing certificate + CI secrets Sign dist\ProxyChainManager.exe in release pipeline once cert is provisioned

High (P1) — design / scope debt

ID Why left open
E-01 Refresh real_ip when VPN state changes mid-session — needs interval policy
E-02E-05 Sticky exit / leak semantics need a product rule (rotate vs warn)
E-07E-10 Pool/pinned/exit edge cases need operator UX
E-12E-13 DNS leak methodology (DoH vs system DNS) needs spec
E-14 / S-08 Kill-switch DNS allow rule is required for GOST hostname resolution
E-16E-18 OS adapter / MAC spoof crash recovery
E-21 Boot task LIMITED vs admin kill-switch
E-22 Group Policy proxy-lock remediation (destructive — needs explicit operator consent)
E-23 Auto-rewrite of sanitized settings — needs UI toggle
E-28E-30 Third-party intel APIs / map geo / GOST blacklist rules
M-01M-03, M-05, M-07M-14 README alignment, encrypted vault export, ban history, IPv6 chain path, tray click-through
U-01, U-02, U-04, U-05, U-07U-10 Tray/minimize UX, admin-relaunch save state, cookie menu keys, password masking
T-01T-14 Larger test-coverage program
B-03, B-06B-10 UAC manifest tradeoff, GOST bundling, SBOM, Defender scope

Medium (P2)

Installer polish, metrics, coverage gates, IPv6 chain path, SOCKS5 remote DNS policy (browser_profile.py:125 — likely intentional for Firefox+GOST).


11. Remediation log — 2026-05-22 (round 2)

ID Status Notes
C-03 / S-01 Fixed secrets_store.py (Windows DPAPI via ctypes — no new deps). Signup passwords + draft passwords now encrypted on disk; legacy plaintext migrates automatically on first save
C-07 Fixed New validate_pinned_on_start setting + _probe_tcp helper in service.py; dead pinned hops logged but used
C-11 Fixed gost_util.py writes gost.exe.sha256 sidecar on extract and re-verifies on every reuse; mismatch triggers re-download
E-15 Fixed app.py _start() confirms with operator before starting chain without admin when kill-switch is enabled
E-19 Fixed browser_launcher.py is_running() walks the spawned PID's descendants via WMIC instead of pattern-matching any firefox.exe
E-20 Fixed max_browser_relaunches setting + counter in app.py; auto-relaunch self-disables after N failures
E-25 Fixed Dead ban_tester.check_dns_leak() removed (use dns_leak.run_dns_leak_test)
M-04 Fixed Settings tab now has “⚠ Emergency disengage firewall now” button with confirm
U-03 Fixed Window title now reads Proxy God v{__version__}
B-04 Fixed New dev-requirements.txt pins pyinstaller==6.10.0; build script installs it
B-05 Fixed Build script emits ProxyChainManager.exe.sha256 next to the exe and copies it to Desktop

Test suite: 47 → 53 passing (added 6 round-trip tests for secrets_store).


Proxy God Audit — last updated 2026-05-22 (round 2)