Skip to content

fix(security): phase 2 hardening batch - #205

Merged
abarghoud merged 2 commits into
testingfrom
security/phase-2-hardening
Jul 27, 2026
Merged

fix(security): phase 2 hardening batch#205
abarghoud merged 2 commits into
testingfrom
security/phase-2-hardening

Conversation

@abarghoud

Copy link
Copy Markdown
Owner

Summary

Second phase of the security hardening program (follow-up to 346bd15). Closes the CORS localhost finding (contre-expertise F2 / P2-6) and removes the last JavaScript-readable token window in the web OAuth flow.

Changes

Auth cookie flow (api + webapp)

  • The temporary OAuth callback token (sentryguard_temp_token) is now httpOnly: true, sameSite: 'strict', scoped to path: '/auth/session', and host-only (no Domain attribute) — it is no longer readable by JavaScript or by sibling subdomains during its 60s lifetime.
  • New POST /auth/session/exchange endpoint: reads the httpOnly cookie server-side, validates the JWT, clears the cookie, and returns the token in the response body (throttled with publicSensitive).
  • The webapp callback exchanges the cookie via apiClient.request(..., { credentials: 'include' }) instead of reading/deleting it from document.cookie.
  • Removed the now-unused getCookieDomain heuristics and the COOKIE_DOMAIN / NEXT_PUBLIC_COOKIE_DOMAIN environment variables (docs updated accordingly in SELF_HOSTING.md).

CORS (api)

  • localhost:4200/3000/8081/19006 origins are only allowed when NODE_ENV !== 'production' — a local service on a victim's machine no longer gets an authorized credentialed origin in production.

Consent (api)

  • POST /consent/revoke is now throttled with the critical policy (it calls the Tesla partner API to delete the vehicle telemetry configuration).

Telegram webhook (api)

  • Both secret comparisons now go through a single constant-time isSecretValid() helper (node:crypto timingSafeEqual + explicit length pre-check), replacing the try/catch control flow. Covered by a new dedicated spec (6 cases: wrong/short path secret, missing/wrong/valid header secret, delegation).

Testing

  • nx run-many -t lint --projects=api,webapp
  • nx run-many -t test --projects=api,webapp --skip-nx-cache ✅ (including new specs for exchangeSession, the callback cookie attributes, the session-exchange hook flow, and the webhook controller)

Notes

  • The private security docs (SECURITY_ARCHITECTURE.md §4.1, SECURITY_RECOMMENDATIONS.md P2-6 + Recently Completed) need a follow-up update after merge.

- Transfer the OAuth callback JWT via an httpOnly, SameSite=Strict cookie scoped to /auth/session, exchanged server-side through POST /auth/session/exchange instead of being read from JavaScript
- Restrict localhost CORS origins to non-production environments
- Throttle POST /consent/revoke with the critical throttle policy
- Compare Telegram webhook secrets through a constant-time helper with explicit length check
@abarghoud
abarghoud merged commit 23ce2e7 into testing Jul 27, 2026
3 checks passed
@abarghoud
abarghoud deleted the security/phase-2-hardening branch July 27, 2026 14:25
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.

2 participants