Skip to content

Security audit fixes + open-source prep - #14

Merged
jamierpond merged 3 commits into
mainfrom
Jp/sec-audit
Feb 11, 2026
Merged

Security audit fixes + open-source prep#14
jamierpond merged 3 commits into
mainfrom
Jp/sec-audit

Conversation

@jamierpond

Copy link
Copy Markdown
Owner

Summary

  • Device-token HTTP auth: Replaces raw PIN in Authorization: Bearer headers with SHA-256(PIN + deviceToken). Device tokens are 32-byte random hex strings issued at pairing with 6-month TTL. Validates via timingSafeEqual with rate limiting.
  • Open-source prep: Scrubbed personal domains from CLAUDE.md/service file, added .env.example, rewrote README, removed ideas/ dir and stale foo.txt.
  • Token expiry UX: Warning banners at 14 days (dismissible) and 7 days (non-dismissible), auto-redirect on expiry with re-pair flow.

Addresses (from SEC_AUDIT.md)

  • HTTP API endpoints now require authenticated device tokens
  • Rate limiting on HTTP auth attempts
  • Path traversal in static file serving (not in this PR)
  • CORS wildcard (not in this PR)
  • projectId path traversal (not in this PR)

Test plan

  • Fresh pair: verify deviceToken + tokenExpiresAt returned and stored
  • HTTP API calls send SHA-256(pin + deviceToken) as Bearer token
  • Expired device token rejected with device_expired error
  • Unauthenticated HTTP requests get 401
  • Rate limiting triggers 429 after 5 failed attempts
  • Token expiry banner shows at <14 days, non-dismissible at <7 days

🤖 Generated with Claude Code

jamierpond and others added 3 commits February 10, 2026 09:43
- Remove junk files (foo.txt, AGENTS.md)
- Remove `private: true` from package.json, add repository field
- Replace all hardcoded pond.audio URLs with env vars
- Replace hardcoded /home/jamie paths in systemd service with %h specifier
- Genericize SEC_AUDIT.md, CLAUDE.md, ideas/ docs
- Add .env.example with documented config
- Update LICENSE copyright year

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add LLM-generated code disclosure banner
- Add PWA installation instructions (iOS + Android)
- Rewrite getting started with clone, config, systemd setup
- Add "How It Works" section explaining pairing/auth/chat flow
- Remove ideas/ directory (internal planning docs)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HTTP API previously sent the raw PIN in Bearer headers. Now uses
SHA-256(PIN + deviceToken) where deviceToken is a random 32-byte
hex string issued at pairing time with a 6-month TTL.

- Device tokens generated at pairing, stored in devices.json
- HTTP auth validates hash against all non-expired devices (timingSafeEqual)
- Rate limiting added to HTTP auth (reuses WebSocket rate limiter)
- Client computes auth hash via Web Crypto SHA-256
- Token expiry warnings in UI (14d dismissible, 7d non-dismissible)
- Expired devices rejected with device_expired error + re-pair flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jamierpond
jamierpond merged commit ce013c8 into main Feb 11, 2026
4 checks passed
@jamierpond
jamierpond deleted the Jp/sec-audit branch February 11, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant