Skip to content

GhostBus v0.5.3 — hardening round 2

Choose a tag to compare

@littlestjames82-sys littlestjames82-sys released this 11 Oct 09:46
· 53 commits to main since this release

Hardening round 2 — the layer under v0.5.2's defaults.

What changed

  • Timing-safe secret compares everywhere. The hosted workspace-key check, the core agent-token check, and the serverless pack each compared hashes with plain ===; all now use hash-then-timingSafeEqual. No plain secret compares remain.
  • Hosted failed-auth throttle. After 30 failed key/admin attempts per minute from one IP, the hosted server returns 429 on admin and workspace routes (valid traffic and /health unaffected once it clears). Guessing keys at a paid host is now expensive.
  • 1 MB request-body cap on every JSON route (hosted admin, in-workspace, single relay): oversized bodies get a clean 413. Note: workspace exports over 1 MB can no longer be imported over HTTP — use the CLI or place the state file (documented).
  • Board + landing headers: X-Frame-Options: DENY and a content security policy (frame-ancestors 'none', object-src 'none'; inline script/style allowed because the board is one self-contained page loading zero external resources).
  • Data files are 0600. Workspace state and the registry hold key/token hashes; they're now written owner-only via the atomic save path.
  • Generic 500s. Internal errors log server-side (with stack) and return {error:'internal error'} — no internals leaked to clients. Deliberate 400 validation/auth errors are unchanged.
  • Admin audit log. Workspace create/delete/rotate-key/export/import each emit one structured line (timestamp, action, workspace, IP) — never keys or hashes.
  • SECURITY.md added: supported version, reporting address, one-business-day acknowledgement.

Verified: 54 checks in the main suite (was 51; the 3 new checks fail on v0.5.2 for exactly the intended reasons), serverless 6/6, both demos, live hosted smoke.

Scope boundary, honestly: the auth throttle is per-IP and in-memory — behind a shared NAT, one guesser can briefly 429 that IP's unauthenticated attempts. Timing safety is verified by audit + functional checks; a timing channel isn't observable from a functional test.