Skip to content

fix: Safari magic link redirect on MacOS#3799

Closed
deepshekhardas wants to merge 1 commit into
triggerdotdev:mainfrom
deepshekhardas:fix/1384-safari-magic-link-redirect
Closed

fix: Safari magic link redirect on MacOS#3799
deepshekhardas wants to merge 1 commit into
triggerdotdev:mainfrom
deepshekhardas:fix/1384-safari-magic-link-redirect

Conversation

@deepshekhardas
Copy link
Copy Markdown

Fixes #1384

Safari's Intelligent Tracking Prevention (ITP) blocks session cookies set during OAuth/magic link redirect flows when the navigation originates from a cross-site context (e.g., clicking a magic link in an email).

The root cause was the session cookie's SameSite=Lax attribute. While Lax allows cookies on top-level GET navigations, Safari ITP can still block the setting of new cookies on the response during cross-site navigations where the user has no prior interaction with the domain.

Changed sameSite to "none" in production (where secure: true and HTTPS is used), which tells the browser to allow the cookie in cross-site contexts. Development on localhost retains "lax" since localhost does not have HTTPS (required for SameSite=None).

Changed file: apps/webapp/app/services/sessionStorage.server.ts

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 2, 2026

⚠️ No Changeset found

Latest commit: 96e5ff0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Hi @deepshekhardas, thanks for your interest in contributing!

This project requires that pull request authors are vouched, and you are not in the list of vouched users.

This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details.

@github-actions github-actions Bot closed this Jun 2, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a450131b-94cc-4db8-8aff-481d80b9164c

📥 Commits

Reviewing files that changed from the base of the PR and between 2dd9f37 and 96e5ff0.

📒 Files selected for processing (1)
  • apps/webapp/app/services/sessionStorage.server.ts

Walkthrough

The session cookie configuration in sessionStorage.server.ts updates the sameSite attribute to be environment-dependent. In production, it is set to "none"; in all other environments, it defaults to "lax". This replaces the previous fixed "lax" value and enables different cross-domain cookie behavior between production and non-production deployments.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

View 1 additional finding in Devin Review.

Open in Devin Review

cookie: {
name: "__session",
sameSite: "lax",
sameSite: env.NODE_ENV === "production" ? "none" : "lax",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Changing sameSite to "none" in production removes CSRF protection from the session cookie

Setting sameSite: "none" means the __session cookie will be sent on all cross-site requests in production. The application has no alternative CSRF protection mechanism — no CSRF tokens, no double-submit cookies — as confirmed by searching the codebase for "csrf"/"CSRF". The only references to CSRF in the entire webapp are comments noting that sameSite: "lax" itself is the CSRF defense (e.g. apps/webapp/app/services/impersonation.server.ts:12). Every other cookie in the app (impersonation, onboardingSession, referralSource, redirectTo, gitHubSession, lastAuthMethod, uiPreferences, OAuth state cookies) all remain sameSite: "lax". An attacker could host a page that issues POST requests (or other state-changing methods) to the Trigger.dev webapp, and the victim's session cookie would be included automatically — allowing task triggers, settings changes, or other authenticated actions without consent.

Prompt for agents
The change from sameSite: 'lax' to sameSite: 'none' removes the application's only CSRF protection for the session cookie. The app has no CSRF token mechanism to compensate.

If cross-site cookie sending is genuinely needed (e.g. for an iframe embed scenario), you must add an alternative CSRF protection layer — such as per-request CSRF tokens verified on state-changing endpoints, or Origin/Referer header validation. Without such a mechanism, any authenticated POST/PUT/DELETE endpoint is vulnerable to cross-site request forgery.

If the cross-site requirement is narrow (e.g. only needed for specific API endpoints), consider keeping sameSite: 'lax' on the session cookie and using a separate authentication mechanism (like Bearer tokens) for the cross-site use case.

Relevant files: apps/webapp/app/services/sessionStorage.server.ts (the changed file), apps/webapp/app/services/impersonation.server.ts:12 (comment confirming lax = CSRF defense).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

cookie: {
name: "__session",
sameSite: "lax",
sameSite: env.NODE_ENV === "production" ? "none" : "lax",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 All other cookies in the webapp remain sameSite: "lax" — inconsistent security posture

Every other cookie-based session storage in the webapp hardcodes sameSite: "lax": OAuth state cookies (auth.google.ts:35, auth.github.ts:35), impersonation (impersonation.server.ts:12), onboarding (onboardingSession.server.ts:7), redirect (redirectTo.server.ts:12), referral (referralSource.server.ts:15), GitHub session (gitHubSession.server.ts:12), UI preferences (uiPreferences.server.ts:7), last auth method (lastAuthMethod.server.ts:10), and messages (message.server.ts:42). The main session cookie is the only one being changed to "none". If the intent is to support cross-origin embedding, the other cookies (especially OAuth state cookies) would also need updating, otherwise cross-origin login flows would still fail since the OAuth cookies wouldn't be sent.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

Localhost magic link redirect on Safari (MacOS)

1 participant