fix: audit round 2 - DPAPI secrets, pinned hop probe, gost exe hash, admin guard, PID-scoped browser tracking, emergency disengage button, build sidecar
This commit is contained in:
@@ -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-02–E-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-07–E-10** | Pool/pinned/exit edge cases need operator UX, not one-line fixes |
|
||||
| **E-12–E-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-16–E-18** | OS adapter/MAC spoof recovery after crash |
|
||||
| **E-19–E-20** | Firefox PID tracking / relaunch loop limits |
|
||||
| **E-01** | Refresh `real_ip` when VPN state changes mid-session — needs interval policy |
|
||||
| **E-02–E-05** | Sticky exit / leak semantics need a product rule (rotate vs warn) |
|
||||
| **E-07–E-10** | Pool/pinned/exit edge cases need operator UX |
|
||||
| **E-12–E-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-16–E-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 “don’t 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-28–E-30** | Third-party intel APIs / map geo / GOST blacklist rules |
|
||||
| **M-01–M-14** | README alignment, GUI kill-switch button, encrypted vault, ban history, etc. |
|
||||
| **U-01–U-10** | Tray/minimize UX, admin relaunch save state, About version, cookie menu keys, password masking in list |
|
||||
| **T-01–T-14** | Test coverage expansion |
|
||||
| **B-03–B-10** | UAC manifest, PyInstaller pin, SHA256 sidecar, bundle GOST, SBOM, Defender scope |
|
||||
| **M-01–M-03, M-05, M-07–M-14** | README alignment, encrypted vault export, ban history, IPv6 chain path, tray click-through |
|
||||
| **U-01, U-02, U-04, U-05, U-07–U-10** | Tray/minimize UX, admin-relaunch save state, cookie menu keys, password masking |
|
||||
| **T-01–T-14** | Larger test-coverage program |
|
||||
| **B-03, B-06–B-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)*
|
||||
|
||||
Reference in New Issue
Block a user