fix: prevent cross-app auth session sharing on localhost
Root cause: browsers don't scope cookies by port. With SESSION_DOMAIN= localhost, all three SPAs share cookies. The CookieBearerToken middleware iterated all cookie names and picked the first match, so logging into the organizer app (port 5174) also authenticated the portal (port 5175). Fix: CookieBearerToken now resolves the correct cookie name from the Origin header (same logic as SetAuthCookie trait). It only reads the cookie matching the requesting app — portal origin reads only crewli_portal_token, app origin reads only crewli_app_token, etc. Falls back to first-available cookie when no Origin header is present (server-to-server requests, tests without explicit Origin). Added 3 cross-app isolation tests: - app cookie does NOT authenticate portal requests - portal cookie does NOT authenticate app requests - correct cookie + matching origin = authenticated Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,11 +52,14 @@ On successful login (`POST /auth/login`), the server:
|
||||
### Validation
|
||||
|
||||
The `CookieBearerToken` middleware (registered before `auth:sanctum` in the API middleware stack):
|
||||
1. Checks for any of the three cookie names in the request
|
||||
2. If found, sets the `Authorization: Bearer` header on the request
|
||||
3. Sanctum's existing token validation processes the header normally
|
||||
1. Reads the `Origin` (or `Referer`) header to identify which app is making the request
|
||||
2. Resolves the correct cookie name for that app (e.g. portal origin → `crewli_portal_token`)
|
||||
3. Reads only that cookie and sets `Authorization: Bearer` on the request
|
||||
4. Sanctum's existing token validation processes the header normally
|
||||
|
||||
If an `Authorization` header is already present (e.g. from the portal token flow), the middleware skips cookie injection.
|
||||
**Cross-app isolation:** In local development, all three SPAs share `localhost` (different ports). Browsers do not scope cookies by port, so all three app cookies are sent with every API request. The middleware prevents cross-app authentication by only reading the cookie that matches the requesting app's Origin header. Without this, logging into one app would authenticate all apps.
|
||||
|
||||
If the `Origin` header is absent (e.g. server-to-server requests), the middleware falls back to the first available cookie. If an `Authorization` header is already present (e.g. from the portal token flow), the middleware skips cookie injection entirely.
|
||||
|
||||
### Rotation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user