fix: address P0/P1/P2 audit findings — security, reliability, CI, docs
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

P0 - Critical:
- config.py: add _mask() credential-redaction helper, SETTINGS_SCHEMA_VERSION,
  plaintext-storage warning; corrupt settings.json backed up before defaults
- gost_util.py: pin SHA256 for gost_3.2.6_windows_amd64.zip; verify before
  extraction; _add_defender_exclusion now logs warning on failure
- firewall.py: add emergency_disengage() for atexit/signal use
- service.py: register fw_emergency_disengage via atexit + SIGTERM/SIGINT;
  stop() calls emergency_disengage if thread hangs past 15s timeout
- app.py: wrap main() in top-level except with CTk error dialog + log
- LICENSE: add MIT license file

P1 - Important:
- app.py: switch to RotatingFileHandler (5 MB / 3 backups)
- config.py: settings_version + migrate(); save_settings() writes .bak before
  overwrite; _is_safe_https_url() strips RFC-1918 sources/ip_check_url
- service.py: threading.Lock on _settings; _signal_handler; graceful stop
- requirements.txt: pin exact versions; add cryptography==48.0.0
- .gitignore: add settings.json, credential JSON files, screenshot noise
- tray.py, dns_leak.py, gost_util.py: replace bare except:pass with logging
- CHANGELOG.md: document all session changes

P2 - Nice to have:
- .github/workflows/test.yml: CI on Python 3.10/3.11/3.12 windows-latest
- run.py: --version / -V flag
- docs/OPERATOR_RUNBOOK.md: emergency disengage, proxy leak, GOST, settings

Tests: 47/47 passed (python -m unittest discover -s tests -v)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Dr Jones
2026-05-21 23:49:02 -07:00
parent 2ba43c3ff9
commit 792b320257
15 changed files with 625 additions and 24 deletions

View File

@@ -89,11 +89,14 @@ from .vpn_detect import detect_vpn
from .windows_task import install_logon_task, task_exists, uninstall_logon_task
LOG_PATH = app_data_dir() / "proxy_chain_manager.log"
from logging.handlers import RotatingFileHandler as _RotatingFileHandler # noqa: E402
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
handlers=[
logging.FileHandler(LOG_PATH, encoding="utf-8"),
_RotatingFileHandler(
LOG_PATH, maxBytes=5 * 1024 * 1024, backupCount=3, encoding="utf-8"
),
logging.StreamHandler(sys.stdout),
],
)
@@ -142,6 +145,25 @@ def _ts() -> str:
def main() -> None:
try:
_main_inner()
except Exception as _exc: # noqa: BLE001
_log = logging.getLogger(__name__)
_log.exception("Unhandled exception in main loop")
try:
import tkinter.messagebox as _mb
_mb.showerror(
"Proxy God — Fatal Error",
f"An unexpected error occurred and the application must close.\n\n"
f"{type(_exc).__name__}: {_exc}\n\n"
f"Details have been written to:\n{LOG_PATH}",
)
except Exception:
pass
raise
def _main_inner() -> None:
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("dark-blue")