HERMES-GIELIE/api
Nathan Esquenazi 39066bc614
security: fix env race, signing key, upload traversal, password hash (#106)
* security: fix four audit findings -- env race, signing key, upload traversal, password hash

1. Race condition in os.environ (HIGH): Per-session _agent_lock didn't
   prevent cross-session env writes from interleaving. Added global
   _ENV_LOCK in streaming.py that serializes the entire env save/restore
   block across all sessions.

2. Predictable signing key (MEDIUM): sha256(STATE_DIR) was deterministic.
   Now generates a random 32-byte key on first startup and persists it to
   STATE_DIR/.signing_key (chmod 600). Existing sessions invalidated on
   first restart (acceptable for a security fix).

3. Upload path traversal (MEDIUM): Filename '..' survived the regex
   sanitization (dots are allowed chars). Added explicit rejection of
   dot-only names and safe_resolve_ws() check to verify the resolved
   path stays within the workspace.

4. Weak password hashing (MEDIUM): Replaced bare SHA-256 with PBKDF2-
   SHA256 (600k iterations per OWASP). Uses stdlib hashlib.pbkdf2_hmac,
   no new dependencies. Note: existing passwords must be re-set after
   this change (hash format changed).

Closes #106

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use random signing key as PBKDF2 salt (replaces predictable STATE_DIR salt)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:25:08 -07:00
..
__init__.py Hermes Web UI — Sprints 11-14: multi-provider models, settings, session QoL, alerts, polish 2026-03-31 07:02:47 +00:00
auth.py security: fix env race, signing key, upload traversal, password hash (#106) 2026-04-04 22:25:08 -07:00
config.py feat: Sprint 26 — pluggable UI themes (dark, light, solarized, monokai, nord) 2026-04-04 20:48:05 -07:00
helpers.py feat: Sprint 19 — password auth, security headers, login page 2026-04-03 05:53:26 -07:00
models.py fix: allow deleting CLI sessions from sidebar (#87) 2026-04-04 17:33:55 -07:00
profiles.py fix(review): 4 issues found in agent review of PR #45 2026-04-03 13:58:43 -07:00
routes.py feat: opt-in state.db sync for /insights visibility (#92) 2026-04-04 20:07:05 -07:00
state_sync.py fix: state_sync.py -- correct class name, constructor type, title API, connection leak 2026-04-04 20:08:20 -07:00
streaming.py security: fix env race, signing key, upload traversal, password hash (#106) 2026-04-04 22:25:08 -07:00
upload.py security: fix env race, signing key, upload traversal, password hash (#106) 2026-04-04 22:25:08 -07:00
workspace.py fix: correct modified/untracked counting in git status parser 2026-04-04 14:25:07 -07:00