Port browser security without changing reference API #56

Merged
erik merged 1 commit from feat/task-b5bdccf3-browser-security into main 2026-10-25 19:11:05 -05:00
Owner

Summary

Port browser security from the current Slugkit template while retaining slugkit.com's reference-host API behavior.

  • Add signed, expiring session/anonymous-bound CSRF tokens plus trusted Origin checks before browser mutations.
  • Add baseline security headers and per-response nonce CSP; wire trusted forms/scripts, passkey fetches and canonical proxy-safe auth URLs.
  • Preserve /cli/auth as a read-only GET/HEAD confirmation page; issue keys only via authenticated, CSRF-protected POST. GET logout no longer mutates sessions.
  • Adapt CSP/CDN/nonces to exact-semver documentation routes, including the contract selector and archived read-only Swagger views.
  • Keep packaged OpenAPI bytes, exact-version live API routes, archive discovery, historical schemas and stricter publish-body validation unchanged.
  • Document optional shared CSRF signing keys/canonical origin and leave HSTS disabled by default.

Task: task-b5bdccf3

Verification

  • ./scripts/pre-pr.sh: PASS (formatting, typecheck, CSS/build reproducibility, all 446 tests across 48 files).
  • Signed Follow integration now exercises the real application middleware, not just the Fedify instance.
  • Local isolated browser fixture: settings save; CLI confirmation and POST issuance; exact-version Swagger with real CDN assets; historical selector/read-only docs; live tag search/color mode; real-token same-site cross-origin form rejection with unchanged key count. All seven browser evidence checklist items proven/audited; no CSP errors in normal UI/docs flows.
  • Fixture uses only an in-memory database, synthetic identities/keys, deterministic archive documents, disabled federation and no production credentials. It can be run explicitly with npm exec tsx -- scripts/security-browser-fixture.ts; never add browser/container/federation tests to CI/release workflows.
  • Real OS/personal passkey interactions were not exercised in this browser session; deterministic passkey workflow tests pass.

Operational boundary

No release tag, image publication, production deployment, homelab mutation, database migration or identity/key rotation. Before a separately approved deployment, verify/configure the canonical browser origin and review proxy-header ownership. HSTS remains opt-in. Existing sessions/data/keys are preserved; ephemeral CSRF signing means open forms must reload after application restart unless an operator supplies a persistent/shared signing key.

## Summary Port browser security from the current Slugkit template while retaining slugkit.com's reference-host API behavior. - Add signed, expiring session/anonymous-bound CSRF tokens plus trusted Origin checks before browser mutations. - Add baseline security headers and per-response nonce CSP; wire trusted forms/scripts, passkey fetches and canonical proxy-safe auth URLs. - Preserve `/cli/auth` as a read-only GET/HEAD confirmation page; issue keys only via authenticated, CSRF-protected POST. GET logout no longer mutates sessions. - Adapt CSP/CDN/nonces to exact-semver documentation routes, including the contract selector and archived read-only Swagger views. - Keep packaged OpenAPI bytes, exact-version live API routes, archive discovery, historical schemas and stricter publish-body validation unchanged. - Document optional shared CSRF signing keys/canonical origin and leave HSTS disabled by default. Task: task-b5bdccf3 ## Verification - `./scripts/pre-pr.sh`: PASS (formatting, typecheck, CSS/build reproducibility, all 446 tests across 48 files). - Signed Follow integration now exercises the real application middleware, not just the Fedify instance. - Local isolated browser fixture: settings save; CLI confirmation and POST issuance; exact-version Swagger with real CDN assets; historical selector/read-only docs; live tag search/color mode; real-token same-site cross-origin form rejection with unchanged key count. All seven browser evidence checklist items proven/audited; no CSP errors in normal UI/docs flows. - Fixture uses only an in-memory database, synthetic identities/keys, deterministic archive documents, disabled federation and no production credentials. It can be run explicitly with `npm exec tsx -- scripts/security-browser-fixture.ts`; never add browser/container/federation tests to CI/release workflows. - Real OS/personal passkey interactions were not exercised in this browser session; deterministic passkey workflow tests pass. ## Operational boundary No release tag, image publication, production deployment, homelab mutation, database migration or identity/key rotation. Before a separately approved deployment, verify/configure the canonical browser origin and review proxy-header ownership. HSTS remains opt-in. Existing sessions/data/keys are preserved; ephemeral CSRF signing means open forms must reload after application restart unless an operator supplies a persistent/shared signing key.
feat: port browser security protections
All checks were successful
CI / verify (pull_request) Successful in 1m38s
fafdebe76c
Task: #task-b5bdccf3
Author
Owner

Independent review — fafdebe76c

A fresh, read-only Pi reviewer inspected the full diff and relevant surrounding code with only read/grep/find/ls tools. Result: No actionable defects found. Review checked CSRF/session/origin binding, nonce/cache isolation, CLI POST issuance and read-only GET/HEAD, retained API/schema/archive behavior, and opt-in HSTS.

Optional suggestion: exact-version/SRI pinning of Swagger CDN assets for reproducibility. Deferred as non-blocking follow-up; this port follows the reviewed template's stable-major Swagger assets and explicitly nonces trusted scripts.

Review limits: static independent review; reviewer did not independently rerun tests or browser checks. The implementation session separately verified ./scripts/pre-pr.sh (446 tests/48 files), isolated browser journeys, and successful Forgejo CI run #53 for this exact commit. Real OS/personal passkeys were not exercised.

The initial Claude Code reviewer was unavailable due to expired authentication; the successful independent review used a separate Pi context, not a self-review substitution. No credentials were changed.

Pipeline gates: local checks PASS; PR CI PASS (verified through fj actions tasks, because fj pr status has a response-parsing bug); independent review PASS. No release tag, image publication, or production deployment is authorized or performed.

## Independent review — fafdebe76c81fc77670583e63ce56a47b6ff7b95 A fresh, read-only Pi reviewer inspected the full diff and relevant surrounding code with only read/grep/find/ls tools. Result: **No actionable defects found.** Review checked CSRF/session/origin binding, nonce/cache isolation, CLI POST issuance and read-only GET/HEAD, retained API/schema/archive behavior, and opt-in HSTS. Optional suggestion: exact-version/SRI pinning of Swagger CDN assets for reproducibility. Deferred as non-blocking follow-up; this port follows the reviewed template's stable-major Swagger assets and explicitly nonces trusted scripts. Review limits: static independent review; reviewer did not independently rerun tests or browser checks. The implementation session separately verified `./scripts/pre-pr.sh` (446 tests/48 files), isolated browser journeys, and successful Forgejo CI run #53 for this exact commit. Real OS/personal passkeys were not exercised. The initial Claude Code reviewer was unavailable due to expired authentication; the successful independent review used a separate Pi context, not a self-review substitution. No credentials were changed. Pipeline gates: local checks PASS; PR CI PASS (verified through `fj actions tasks`, because `fj pr status` has a response-parsing bug); independent review PASS. No release tag, image publication, or production deployment is authorized or performed.
erik merged commit 72711d4827 into main 2026-10-25 19:11:05 -05:00
erik deleted branch feat/task-b5bdccf3-browser-security 2026-10-25 19:11:05 -05:00
Sign in to join this conversation.
No description provided.