Skip to content

v0.1.1 — Security + hardening

Choose a tag to compare

@jcrabapple jcrabapple released this 11 Aug 02:09
· 8 commits to main since this release

Security & code-quality release

Security

  • Path traversal in mirror_browse and delete_mirror — resolved paths are now confined to the mirror/output directory (returns 403/404)
  • XSS in clone log — switched from Alpine x-html to x-text so mirrored page titles can't inject HTML
  • Extension credentials moved from chrome.storage.syncchrome.storage.local (no longer synced to Google's servers)
  • Constant-time credential comparison (hmac.compare_digest) in Basic Auth and login routes

Bugs

  • Missing MB unit label in size formatting
  • Page count pluralization (1 page vs 2 pages)
  • mirror_browse hardcoded text/html mimetype — now guesses from file extension (CSS/JS/images serve correctly in the iframe browser)
  • /api/jobs endpoints no longer leak subprocess stdout lines
  • Missing kage binary raises KageNotFoundError with install instructions instead of crashing the reader thread

Code quality

  • get_mirror is O(1) (direct path check, no full directory scan)
  • Thread-safe job dictionary access (_job_lock on all mutations/reads)
  • get_job_raw added for WebSocket streaming; API-facing get_job returns clean snapshots

Tests

24 → 49 tests. New coverage: parse_clone_output (8 cases), path traversal regression, mimetype, lines exclusion, constant-time auth, _build_mirror.

Docs

  • README screenshots (dashboard + mirror detail) added in v0.1.0 follow-up