Redirect Cookie Behavior

Understanding how cookies behave when following HTTP redirects is crucial for cookie management in web applications.

Types of Redirects

301 Permanent Redirect

302 Temporary Redirect

Flow:

  1. User visits redirect.example.com
  2. Server sets cookie: Set-Cookie: session=abc; Domain=redirect.example.com
  3. Server responds with 301 redirect to target.example.com
  4. Browser follows redirect
  5. Request to target.example.com includes cookie from redirect domain

Important: Cookies are sent with the redirect request if:

Sequence Diagram:

sequenceDiagram participant User participant Redirect as Redirect Domain
(redirect.example.com) participant Target as Target Domain
(target.example.com) participant Browser User->>Redirect: GET /page HTTP/1.1 Redirect->>Browser: HTTP 200 OK
Set-Cookie: session=abc
Domain=redirect.example.com
SameSite=Lax Browser->>Browser: Store cookie for redirect.example.com Note over Browser: User action triggers redirect Browser->>Redirect: GET /redirect HTTP/1.1
Cookie: session=abc Redirect->>Browser: HTTP 301 Moved Permanently
Location: https://target.example.com/page Browser->>Browser: Process redirect (top-level navigation) Browser->>Target: GET /page HTTP/1.1
Cookie: session=abc Note over Browser,Target: Cookie sent because:
SameSite=Lax allows top-level navigation Target->>Browser: HTTP 200 OK
Content: Target page

Flow:

  1. User visits redirect.example.com
  2. Server responds with 301 redirect to target.example.com
  3. Browser follows redirect to target.example.com
  4. Server sets cookie: Set-Cookie: session=xyz; Domain=target.example.com
  5. Cookie is stored for target domain

Sequence Diagram:

sequenceDiagram participant User participant Redirect as Redirect Domain
(redirect.example.com) participant Target as Target Domain
(target.example.com) participant Browser User->>Redirect: GET /page HTTP/1.1 Redirect->>Browser: HTTP 301 Moved Permanently
Location: https://target.example.com/page Browser->>Browser: Follow redirect (automatic) Browser->>Target: GET /page HTTP/1.1
Cookie: (none from redirect domain) Target->>Browser: HTTP 200 OK
Set-Cookie: session=xyz
Domain=target.example.com
Path=/
SameSite=Lax Browser->>Browser: Store cookie for target.example.com Note over Browser,Target: Cookie set on target domain
Stored for future requests to target

Scenario 3: Cross-Domain Redirect

Flow:

  1. User visits redirect.example.com
  2. Server responds with 301 redirect to target.example.com (different domain)
  3. Browser follows redirect

Cookie Considerations:

Critical Domain Attribute Requirement:

For a cookie set on redirect.example.com to be sent to target.example.com after a redirect, the cookie's Domain attribute must explicitly allow the target domain. Simply having SameSite=Lax is not sufficient:

Important: The browser checks both the Domain attribute AND the SameSite policy. Both must allow the cookie to be sent. [^2]

Sequence Diagram - SameSite=Lax:

sequenceDiagram participant User participant Redirect as Redirect Domain
(redirect.example.com) participant Target as Target Domain
(target.example.com) participant Browser User->>Redirect: GET /page HTTP/1.1 Redirect->>Browser: Set-Cookie: session=abc
Domain=redirect.example.com
SameSite=Lax Browser->>Browser: Store cookie Note over User: User clicks link or navigates Browser->>Redirect: GET /redirect HTTP/1.1
Cookie: session=abc Redirect->>Browser: HTTP 301 Moved Permanently
Location: https://target.example.com/page Browser->>Target: GET /page HTTP/1.1
Cookie: session=abc Note over Browser,Target: Cookie sent because:
Domain attribute allows target domain
AND SameSite=Lax allows top-level navigation redirects Target->>Browser: HTTP 200 OK

Sequence Diagram - SameSite=Strict:

sequenceDiagram participant User participant Redirect as Redirect Domain
(redirect.example.com) participant Target as Target Domain
(target.example.com) participant Browser User->>Redirect: GET /page HTTP/1.1 Redirect->>Browser: Set-Cookie: session=abc
Domain=redirect.example.com
SameSite=Strict Browser->>Browser: Store cookie Browser->>Redirect: GET /redirect HTTP/1.1
Cookie: session=abc Redirect->>Browser: HTTP 301 Moved Permanently
Location: https://target.example.com/page Browser->>Target: GET /page HTTP/1.1
Cookie: (session cookie NOT sent) Note over Browser,Target: Cookie NOT sent because:
SameSite=Strict blocks cross-site redirects Target->>Browser: HTTP 200 OK

SameSite=Lax Nuances with Redirects

While SameSite=Lax cookies are generally sent with top-level navigation redirects, there are important subtleties:

What Works:

Browser Behavior Variations:

  1. Redirect Chains: In a chain of redirects (A → B → C), browsers may treat intermediate redirects differently:

    • First redirect (A → B): Cookie may be sent if it's a top-level navigation
    • Subsequent redirects (B → C): Behavior varies by browser and how the redirect chain is tracked
    • Some browsers treat the entire chain as a single navigation context
    • Others may evaluate each redirect separately
  2. Cross-Site → Same-Site Chains: A redirect chain that goes from cross-site to same-site may have different behavior:

    • Example: external.com → redirect.example.com → target.example.com
    • Browsers may apply stricter checks to prevent cross-site cookie leakage
    • The cookie's domain must match throughout the chain
  3. POST Redirects: POST requests that result in redirects behave differently:

    • POST → 302 redirect is treated as a GET request (per HTTP spec) [^3]
    • Some browsers may not send SameSite=Lax cookies on POST-initiated redirects [^4]
    • This is a historical quirk and varies by browser implementation

Browser-Specific Considerations:

POST Redirects and Cookie Behavior

POST requests that result in redirects have special considerations:

Flow:

  1. User submits form via POST to redirect.example.com
  2. Server responds with 302 redirect to target.example.com
  3. Browser converts POST to GET (per HTTP spec) and follows redirect [^3]

Cookie Behavior:

Recommendation: For POST redirects, rely on SameSite=None; Secure for cross-site scenarios, or use server-side session management to transfer state.

Redirect Chains and Corner Cases

Redirect chains (multiple redirects in sequence) introduce additional complexity:

Scenario: A → B → C Redirect Chain

  1. User visits site-a.com
  2. Cookie set: Set-Cookie: session=abc; Domain=site-a.com; SameSite=Lax
  3. site-a.com redirects to site-b.com
  4. site-b.com redirects to site-c.com

Cookie Behavior:

Cross-Site → Same-Site Chains:

When a redirect chain spans from cross-site to same-site (e.g., external.com → redirect.example.com → target.example.com), browsers apply additional checks:

Recommendation: Avoid relying on cookies surviving long redirect chains. Use server-side session management or URL parameters (with appropriate security measures) for state transfer.

DNS Redirection and Aliasing

DNS redirection/aliasing is fundamentally different from HTTP redirects. Instead of the server sending a redirect response, multiple domain names resolve to the same IP address or server through DNS configuration (CNAME records, A record aliases, etc.).

Key Differences from HTTP Redirects

HTTP Redirects:

DNS Aliasing:

When multiple domains resolve to the same server via DNS:

  1. Separate Cookie Jars: Each domain maintains its own cookie storage

    • alias1.example.com and alias2.example.com have separate cookies
    • Cookie set on alias1 is NOT accessible from alias2
  2. No Cross-Domain Cookie Access: Unless parent domain is used

    • Cookie with Domain=alias1.example.com only works on alias1
    • Cookie with Domain=alias2.example.com only works on alias2
    • Cookie with Domain=example.com works on both aliases
  3. SameSite Policy: Applies to actual navigation, not DNS resolution

    • Navigation from alias1 to alias2 is cross-site
    • SameSite=Strict blocks cookie sending
    • SameSite=Lax allows top-level navigation

Scenario: DNS Aliased Domains

Flow:

  1. DNS configured: alias1.example.com → 192.0.2.1
  2. DNS configured: alias2.example.com → 192.0.2.1 (same server)
  3. User visits alias1.example.com
  4. Server sets cookie: Set-Cookie: session=abc; Domain=alias1.example.com
  5. User navigates to alias2.example.com
  6. Cookie is NOT sent (different domain)

Sequence Diagram:

sequenceDiagram participant User participant DNS as DNS Server participant Alias1 as alias1.example.com
(192.0.2.1) participant Alias2 as alias2.example.com
(192.0.2.1) participant Browser User->>Browser: Navigate to alias1.example.com Browser->>DNS: DNS lookup: alias1.example.com DNS-->>Browser: A record: 192.0.2.1 Browser->>Alias1: GET / HTTP/1.1
Cookie: (none) Alias1->>Browser: HTTP 200 OK
Set-Cookie: session=abc
Domain=alias1.example.com
SameSite=Lax Browser->>Browser: Store cookie for alias1.example.com Note over Browser: User navigates to alias2 User->>Browser: Navigate to alias2.example.com Browser->>DNS: DNS lookup: alias2.example.com DNS-->>Browser: A record: 192.0.2.1 (same IP) Browser->>Browser: Check cookies for alias2.example.com Browser->>Browser: No cookies found (different domain) Browser->>Alias2: GET / HTTP/1.1
Cookie: (none) Note over Browser,Alias2: Cookie NOT sent because
alias1 and alias2 are different domains Alias2->>Browser: HTTP 200 OK

Using Parent Domain for Shared Cookies

To share cookies across DNS-aliased domains, use the parent domain:

Configuration:

Sequence Diagram - Parent Domain Cookie:

sequenceDiagram participant User participant Alias1 as alias1.example.com
(192.0.2.1) participant Alias2 as alias2.example.com
(192.0.2.1) participant Browser User->>Browser: Navigate to alias1.example.com Browser->>Alias1: GET / HTTP/1.1
Cookie: (none) Alias1->>Browser: HTTP 200 OK
Set-Cookie: session=abc
Domain=example.com
SameSite=Lax Browser->>Browser: Store cookie for example.com
(parent domain) Note over Browser: User navigates to alias2 User->>Browser: Navigate to alias2.example.com Browser->>Browser: Check cookies for alias2.example.com Browser->>Browser: Match found: session cookie
(alias2 is subdomain of example.com) Browser->>Alias2: GET / HTTP/1.1
Cookie: session=abc Note over Browser,Alias2: Cookie sent because:
alias2.example.com is subdomain
of example.com Alias2->>Browser: HTTP 200 OK

Common DNS Aliasing Scenarios

Scenario 1: Multiple Subdomains

Scenario 2: International Domains

Scenario 3: Branding Aliases

Differences from HTTP Redirects

Aspect HTTP Redirect DNS Alias
Browser Awareness Sees redirect response Sees direct request
Cookie Sharing Depends on SameSite policy Requires parent domain
Request Count 2 requests (original + redirect) 1 request per domain
Developer Tools Shows redirect chain Shows direct request
Cross-Domain Navigation SameSite applies to redirect SameSite applies to navigation

Testing DNS Aliasing

When testing DNS aliases in the playground or any environment:

  1. Verify DNS Resolution:

    dig alias1.example.com
    dig alias2.example.com
    # Both should resolve to same IP
  2. Check Cookie Isolation:

    • Set cookie on alias1
    • Navigate to alias2
    • Verify cookie is NOT accessible
  3. Test Parent Domain Cookie:

    • Set cookie with Domain=example.com
    • Navigate between alias1 and alias2
    • Verify cookie IS accessible on both
  4. Inspect in DevTools:

    • Network tab: Check Host header (shows actual domain)
    • Application tab: Check cookies per domain
    • No redirect entries (unlike HTTP redirects)

Important Notes

Testing in the Playground

Setup

  1. Redirect Domain: site-c.cookie-playground.pun7o.click

    • All requests return 301 redirect
    • Redirects to: site-a.cookie-playground.pun7o.click
  2. Target Domain: site-a.cookie-playground.pun7o.click

    • Receives redirected requests
    • Has redirect test page: /redirect-test.html

Test Procedures

  1. Visit https://site-c.cookie-playground.pun7o.click
  2. Observe 301 redirect in browser DevTools
  3. Check cookies on target domain
  4. Verify redirect preserves query parameters
  1. Set cookie on redirect domain (if possible via JavaScript before redirect)
  2. Follow redirect
  3. Check if cookie persists on target domain
  1. Follow redirect to target domain
  2. Set cookie on target domain
  3. Verify cookie is stored correctly

Test 4: Programmatic Redirect Following

  1. Use JavaScript fetch with redirect: 'manual'
  2. Inspect redirect response headers
  3. Manually follow Location header
  4. Observe cookie behavior

HTTP Status Codes

301 Moved Permanently

HTTP/1.1 301 Moved Permanently
Location: https://target.example.com/path

302 Found (Temporary)

HTTP/1.1 302 Found
Location: https://target.example.com/path

Important Considerations

Browser Caching

Critical Understanding: A cookie set on redirect.example.com will NOT automatically be accessible on target.example.com after a redirect, even if SameSite=Lax allows the redirect. The Domain attribute must explicitly allow the target domain.

Examples:

Important: Many browsers treat initial navigations with certain flags differently. The Domain attribute is checked before the SameSite policy. Both must allow the cookie to be sent. [^2]

SameSite Policy Impact

Important: The SameSite policy is evaluated after the Domain attribute check. If the domain doesn't match, the cookie won't be sent regardless of SameSite policy. [^2]

Path Matching

Browser Exceptions and Historical Quirks

Browser Version Differences

Older Browser Versions:

Modern Browser Defaults:

SameSite=None; Secure Requirement

For cross-site cookies to work with redirects, they must include both:

Example:

Set-Cookie: session=abc; Domain=example.com; SameSite=None; Secure

Why: This requirement prevents insecure cross-site cookie transmission and protects against man-in-the-middle attacks. [^1]

HTTP Working Group Issue #889

The HTTP working group has documented divergences in how browsers treat SameSite=Strict and SameSite=Lax cookies after cross-site redirects. [^4] Key points:

Recommendation: Don't rely on cookies surviving cross-site redirect chains. Use explicit domain matching and consider server-side session management for critical state.

Browser-Specific Behaviors

Chrome/Edge (Chromium):

Firefox:

Safari:

Testing Recommendation: Always test redirect cookie behavior in your target browsers, especially Safari if you have Mac/iOS users.

Browser Behavior Comparison Table

Behavior Chrome/Edge (80+) Firefox (69+) Safari (13+)
Default SameSite SameSite=Lax if not specified [^5] Varies by version Stricter defaults [^7]
SameSite=Lax with GET redirects ✅ Sent with top-level navigation ✅ Sent with top-level navigation ✅ Sent with top-level navigation (may be more restrictive)
SameSite=Lax with POST redirects ⚠️ Usually sent (treated as GET) ⚠️ May vary ⚠️ More restrictive, may block
SameSite=Strict with redirects ❌ Not sent (cross-site) ❌ Not sent (cross-site) ❌ Not sent (cross-site)
SameSite=None; Secure ✅ Sent (requires HTTPS) ✅ Sent (requires HTTPS) ✅ Sent (requires HTTPS)
Redirect chain handling Treats chain as single navigation context May evaluate each redirect separately More restrictive, may block longer chains
301 redirect caching Aggressive caching Moderate caching Moderate caching
Cross-site → same-site chains Generally permissive May be restrictive Very restrictive, may block
Additional protections None None ITP (Intelligent Tracking Prevention) [^8]
Cookie Domain evaluation Domain checked before SameSite [^2] Domain checked before SameSite [^2] Domain checked before SameSite [^2]

Legend:

Common Use Cases

URL Shortening

Domain Migration

CDN Redirects

Troubleshooting

Possible Causes:

  1. Domain mismatch: Cookie Domain attribute doesn't allow target domain (use parent domain cookie)
  2. SameSite policy too restrictive: Policy blocks cross-site redirects
  3. Secure flag missing: Required for SameSite=None, must use HTTPS
  4. Path mismatch: Cookie path doesn't match redirect path
  5. Browser version: Older browsers may not support SameSite correctly
  6. POST redirect: May not work with SameSite=Lax, consider SameSite=None; Secure or server-side session

Solutions:

  1. Domain mismatch: Set Domain to parent domain that encompasses both redirect and target domains

    • Example: Use Domain=example.com for redirect.example.com → target.example.com
  2. SameSite policy: Use SameSite=Lax for top-level navigation redirects or SameSite=None; Secure for cross-site scenarios

  3. Secure flag: Ensure Secure flag is set when using SameSite=None (requires HTTPS)

  4. Path matching: Set cookie path to / to match all paths, or ensure path matches redirect path

  5. Browser compatibility: Test in target browsers, especially Safari for Mac/iOS users

  6. POST redirects: Use SameSite=None; Secure for POST-initiated redirects or server-side session management

Possible Causes:

  1. Domain attribute not set
  2. Cookie expired
  3. Browser privacy settings

Solutions:

Testing Checklist

Additional Resources

Citations

[^1]: RFC 6265bis - HTTP State Management Mechanism . Defines SameSite cookie attribute behavior, including that SameSite=None requires the Secure flag, and specifies when cookies are sent with redirects.

[^2]: RFC 6265 - HTTP State Management Mechanism . Section 5.1.3 defines domain matching rules, and Section 5.2 specifies that domain matching is evaluated before other cookie attributes.

[^3]: RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content . Section 6.4.3 specifies that 302 redirects change POST requests to GET requests.

[^4]: HTTP Working Group Issue #889 . Documents browser divergences in handling SameSite cookies with redirects, particularly POST-initiated redirects.

[^5]: Chrome SameSite Cookie Changes . Chrome 80+ defaults to SameSite=Lax for cookies without an explicit SameSite attribute.

[^6]: Firefox SameSite Cookie Support . Firefox 69+ supports SameSite cookies with varying default behaviors.

[^7]: Safari Intelligent Tracking Prevention . Safari 13+ implements stricter SameSite defaults and additional privacy protections.

[^8]: Safari ITP Documentation . Safari's Intelligent Tracking Prevention includes additional restrictions on cross-site cookie behavior beyond standard SameSite policies.

Next Steps