SECURITY-AUDIT-PLAN.md markdown
120 lines 7.0 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 1 day ago

Security Audit Remediation Plan

Pre-launch security hardening derived from dual-audit cross-reconciliation (April 2026). Each phase commits at completion. Model recommendations reflect task complexity.


Phase 0 — Emergency (Ship-Stoppers) ✅ COMPLETE

Commit: 6749166 Model: claude-4.6-sonnet-medium-thinking (Opus-class for architectural decisions) Deployed: Canister V6→V7 migration live on IC mainnet. Gateway auth secret active.

# Item Status
0.1 Canister gateway auth (X-Gateway-Auth) — Motoko + all gateway callers
0.2 Remove X-Test-User from canister; update CORS allowed headers
0.3 Timing-safe comparisons for HMAC/secret checks (verifyState)
0.4 captureAuth fail-closed when CAPTURE_WEBHOOK_SECRET unset
0.5 POST /api/v1/attest requires JWT authentication
0.6 MCP hosted server canister calls include X-User-Id + X-Gateway-Auth
23 new unit tests; 1270 existing tests passing

Post-deploy verification:

  • curl https://rsovz-byaaa-aaaaa-qgira-cai.raw.icp0.io/api/v1/notes -H "X-User-Id: test"GATEWAY_AUTH_REQUIRED
  • curl https://rsovz-byaaa-aaaaa-qgira-cai.raw.icp0.io/health{"ok":true}

Phase 1 — High Priority (Same Release Train) ✅ COMPLETE

Model: claude-4.6-sonnet-medium-thinking Branch: feature/landing-overview-video-ui

# Item File(s) Status
1.1 Trust proxy for Express rate limiting — real client IPs behind Netlify CDN hub/gateway/server.mjs, hub/server.mjs
1.2 Zip-slip protection — validate each AdmZip entry stays under extract dir hub/bridge/server.mjs, hub/server.mjs
1.3 Self-hosted default-admin startup warning when roleMap.size === 0 in production hub/server.mjs
1.4 Header allowlist for proxyToCanister and proxyTo — replace ...req.headers spread hub/gateway/server.mjs
1.5 Billing enforcement startup warning when BILLING_ENFORCE unset in hosted mode hub/gateway/billing-constants.mjs, hub/gateway/server.mjs
36 new unit tests; 1306 total tests passing test/phase1-security.test.mjs

Phase 2 — CI/CD & Infrastructure ✅ COMPLETE

Model: claude-4.6-sonnet-medium-thinking Branch: feature/landing-overview-video-ui

# Item File(s) Status
2.1 Add npm audit gate to CI — fail on high/critical CVEs .github/workflows/ci.yml
2.2 Add secret scanning to CI (TruffleHog action) .github/workflows/ci.yml
2.3 Add dependency review action on PRs (actions/dependency-review-action) .github/workflows/dependency-review.yml ✅ (workflow later removed — dependency-review-action requires GitHub Advanced Security, which is unavailable on private repos; npm audit gate in ci.yml covers this)
2.4 Dockerfile: non-root user (knowtation), pinned tag (node:20.19.0-alpine3.21), npm ci hub/Dockerfile
2.5 Fix GitHub token encryption salt — random 16-byte per-token salt embedded in ciphertext; v1 tokens gracefully fall back to reconnect hub/bridge/server.mjs
2.6 Upgraded [email protected][email protected]; added sanitizeUploadFilename() — strips path traversal, replaces unsafe chars, truncates to 200 chars hub/bridge/server.mjs, package.json
41 new unit tests; 1347 total tests passing test/phase2-security.test.mjs

Phase 3 — Defense in Depth ✅ COMPLETE

Model: claude-4.6-opus-high-thinking Branch: feature/security-audit Deployed: Canister V7→V8 migration live on IC mainnet. CORS origin locked to gateway.

# Item File(s) Status
3.1 JWT token-in-URL: OAuth redirect uses URL fragment #token=; gateway JWT expiry shortened from 7d24h hub/gateway/server.mjs, hub/server.mjs
3.2 Image proxy ?token= — short-lived HMAC-signed image token (5 min TTL) replaces full JWT in query param; new /api/v1/vault/image-proxy-token endpoint hub/gateway/server.mjs, hub/server.mjs
3.3 Bridge write routes: requireBridgeEditorOrAdmin added to /vault/sync, /index, /memory/store, /memory/clear, /memory/consolidate — viewer role can no longer mutate hub/bridge/server.mjs
3.4 MCP in-memory refresh token store: periodic sweep every 10 min deletes expired entries; destroy() cleans up timer hub/gateway/mcp-oauth-provider.mjs
3.5 CORS on canister: corsHeaders() locks Access-Control-Allow-Origin to stored origin when gateway_auth_secret + cors_allowed_origin are both set; new admin_set_cors_origin function; V7→V8 migration hub/icp/src/hub/main.mo, hub/icp/src/hub/Migration.mo
3.6 path-to-regexp ReDoS CVE resolved: npm audit fix upgraded 0.1.120.1.13 in all three lock files hub/package-lock.json, hub/gateway/package-lock.json, package-lock.json
33 new unit tests; 1380 total tests passing test/phase3-security.test.mjs

Deployment steps for each canister-touching phase

After any Motoko change:

# 1. Export backup first (safety)
npm run canister:export-backup

# 2. Deploy
cd hub/icp && dfx deploy hub --network ic

# 3. If new admin functions added, call them
dfx canister call hub <function_name> '("<secret>")' --network ic

# 4. Verify
curl -s https://rsovz-byaaa-aaaaa-qgira-cai.raw.icp0.io/health

Open verification items (resolve before public launch)

  • [x] Production canister URL confirmed as raw.icp0.io in all Netlify env vars
  • [x] CANISTER_AUTH_SECRET set in Netlify gateway env
  • [x] admin_set_gateway_auth_secret called on IC mainnet canister
  • [x] admin_set_cors_origin called on IC mainnet canister (Phase 3.5 — locked to https://knowtation-gateway.netlify.app)
  • [ ] Netlify function IAM and blob access policies reviewed (not visible in code)
  • [ ] Content Security Policy and cookie flags for Hub static hosting
  • [ ] Log pipeline confirmed — no Authorization or ?token= values logged
  • [ ] Stripe live-mode webhook endpoint idempotency under replay confirmed
  • [ ] BILLING_ENFORCE decision explicit for production

Canister IDs

  • Hub: rsovz-byaaa-aaaaa-qgira-cai
  • Attestation: dejku-syaaa-aaaaa-qgy3q-cai

Key commits

  • Phase 0: 6749166 — canister gateway auth, timing-safe secrets, fail-closed webhook, attest auth
  • Phase 1: 9b37569 — trust proxy, zip-slip, default-admin warning, header allowlist, billing warning
  • Phase 2: (see commit on feature/landing-overview-video-ui) — npm audit CI gate, TruffleHog, dependency review, Dockerfile hardening, per-token salt, multer@2
  • Phase 3: 9a362e5 — token-in-URL fragment, image proxy signed token, bridge RBAC, MCP token sweep, canister CORS lock, path-to-regexp fix

All four audit phases complete. Remaining items above are operational verification, not code changes.

File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 1 day ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 1 day ago