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

@@ -225,48 +225,60 @@ All remaining E/M/B/U/T items, installer signing, metrics, coverage gates
## 10. Still needs to be fixed
Items below were **not** changed in this pass because they need design decisions, external tooling, or behavior that is not safe to guess.
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-03 / S-01** | Encrypting `settings.json` / signup JSON requires key management (DPAPI vs Fernet passphrase) and migration for existing installs | Windows DPAPI via `cryptography` or OS credential store; one-time migration on load |
| **C-07** | Pinned chains need per-hop health probes without breaking intentional manual order | Optional “validate pinned hops on start” toggle + blacklist dead hops only |
| **C-09** | Narrowing signup extension off `<all_urls>` breaks **custom signup URLs** | Dynamic host permissions or user-approved host list per session |
| **C-11** | No pinned SHA256 for extracted `gost.exe` in repo | Add `GOST_EXE_SHA256` constant from official release manifest |
| **C-12** | `asyncio.run()` in worker threads (`app.py` preflight) — refactor needs dedicated event-loop policy | Run network checks via `asyncio.new_event_loop()` in thread or shared async runner |
| **S-03** | `verify=False` on httpx is intentional for broken proxy TLS; enabling verify breaks many public proxies | Per-setting toggle; document risk |
| **B-01** | Authenticode signing needs cert + build pipeline | Sign `dist\ProxyChainManager.exe` in release script |
| **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)
### High (P1) — design / scope debt
| ID | Why left open |
|----|---------------|
| **E-01** | Refresh `real_ip` when VPN state changes mid-session |
| **E-02E-03** | Sticky exit + leak interaction needs product rule (rotate vs warn) |
| **E-04** | `is_chain_leak(real_ip=None)` fail-open — changing affects rotation semantics |
| **E-05** | /16 neighbor policy is intentional without VPN |
| **E-07E-10** | Pool/pinned/exit edge cases need operator UX, not one-line fixes |
| **E-12E-13** | DNS leak test methodology (DoH vs system DNS) needs spec |
| **E-14 / S-08** | Kill-switch DNS allow rule required for GOST hostname resolution |
| **E-15** | Non-admin kill-switch skip — document or block Start without admin |
| **E-16E-18** | OS adapter/MAC spoof recovery after crash |
| **E-19E-20** | Firefox PID tracking / relaunch loop limits |
| **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** | GP proxy lock remediation (destructive) |
| **E-23** | Auto-rewrite sanitized settings — add “dont auto-save” option |
| **E-25** | `ban_tester.check_dns_leak()` uses useless `x-real-ip` header — **dead code**, unused by GUI; remove or replace with `dns_leak.run_dns_leak_test` |
| **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-14** | README alignment, GUI kill-switch button, encrypted vault, ban history, etc. |
| **U-01U-10** | Tray/minimize UX, admin relaunch save state, About version, cookie menu keys, password masking in list |
| **T-01T-14** | Test coverage expansion |
| **B-03B-10** | UAC manifest, PyInstaller pin, SHA256 sidecar, bundle GOST, SBOM, Defender scope |
| **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`may be intentional for Firefox+GOST).
Installer polish, metrics, coverage gates, IPv6 chain path, SOCKS5 remote DNS policy (`browser_profile.py:125`likely intentional for Firefox+GOST).
---
*Proxy God Audit — last updated 2026-05-22*
## 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)*