fix(security): phase 2 hardening batch - #205
Merged
Merged
Conversation
- 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
JordiMa
approved these changes
Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second phase of the security hardening program (follow-up to
346bd15). Closes the CORSlocalhostfinding (contre-expertise F2 / P2-6) and removes the last JavaScript-readable token window in the web OAuth flow.Changes
Auth cookie flow (api + webapp)
sentryguard_temp_token) is nowhttpOnly: true,sameSite: 'strict', scoped topath: '/auth/session', and host-only (noDomainattribute) — it is no longer readable by JavaScript or by sibling subdomains during its 60s lifetime.POST /auth/session/exchangeendpoint: reads the httpOnly cookie server-side, validates the JWT, clears the cookie, and returns the token in the response body (throttled withpublicSensitive).apiClient.request(..., { credentials: 'include' })instead of reading/deleting it fromdocument.cookie.getCookieDomainheuristics and theCOOKIE_DOMAIN/NEXT_PUBLIC_COOKIE_DOMAINenvironment variables (docs updated accordingly inSELF_HOSTING.md).CORS (api)
localhost:4200/3000/8081/19006origins are only allowed whenNODE_ENV !== 'production'— a local service on a victim's machine no longer gets an authorized credentialed origin in production.Consent (api)
POST /consent/revokeis now throttled with thecriticalpolicy (it calls the Tesla partner API to delete the vehicle telemetry configuration).Telegram webhook (api)
isSecretValid()helper (node:cryptotimingSafeEqual+ 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 forexchangeSession, the callback cookie attributes, the session-exchange hook flow, and the webhook controller)Notes
SECURITY_ARCHITECTURE.md§4.1,SECURITY_RECOMMENDATIONS.mdP2-6 + Recently Completed) need a follow-up update after merge.