Same-Site vs Cross-Site Requests

Understanding the difference between same-site and cross-site requests is fundamental to understanding cookie behavior, especially with the SameSite attribute.

Request Classification

Every HTTP request is classified as either same-site or cross-site based on the relationship between:

Same-Site Requests

A same-site request occurs when a request is made to the same domain where the cookie was originally set.

Definition

The cookie is sent whenever a request is made to the same domain it was set on. This is the default behavior for cookies.

Characteristics

Examples

Scenario 1: Same Domain

  1. User visits https://shop.example.com
  2. Server sets cookie: Set-Cookie: session=abc123; Domain=shop.example.com
  3. User navigates to https://shop.example.com/products
  4. Result: Cookie is sent (same-site request)

Scenario 2: Subdomain (with Domain Attribute)

  1. User visits https://shop.example.com
  2. Server sets cookie: Set-Cookie: session=abc123; Domain=example.com
  3. User navigates to https://blog.example.com
  4. Result: Cookie is sent (same-site request, because cookie Domain matches)

Scenario 3: API Request

  1. User visits https://shop.example.com
  2. Cookie exists: session=abc123; Domain=shop.example.com
  3. JavaScript makes request: fetch('https://shop.example.com/api/cart')
  4. Result: Cookie is sent (same-site request)

Cross-Site Requests

A cross-site request occurs when a request is made to a different domain than where the cookie was set.

Important Distinction

Cross-site requests are further classified by:

The behavior differs significantly based on these factors.

Cross-Site GET Requests

The cookie is sent if the user clicks a link on an external website that navigates them to the cookie's site using the GET method.

Definition

Cross-site GET requests that represent top-level navigation will include cookies (depending on SameSite attribute).

Characteristics

Examples

Scenario 1: Link Click

  1. User visits https://external-site.com
  2. Page contains link: <a href="https://shop.example.com/products">Visit Shop</a>
  3. User clicks the link
  4. Cookie exists: session=abc123; Domain=shop.example.com; SameSite=Lax
  5. Result: Cookie is sent with request to shop.example.com (cross-site GET navigation)

Scenario 2: Redirect

  1. User visits https://external-site.com
  2. Server redirects: 301 Redirect to https://shop.example.com/welcome
  3. Cookie exists: session=abc123; Domain=shop.example.com; SameSite=Lax
  4. Result: Cookie is sent with redirect request (cross-site GET navigation)

Scenario 3: GET Form Submission

  1. User visits https://external-site.com
  2. Form on page: <form method="GET" action="https://shop.example.com/search">
  3. User submits form
  4. Cookie exists: session=abc123; Domain=shop.example.com; SameSite=Lax
  5. Result: Cookie is sent (cross-site GET navigation)

Scenario 4: SameSite=Strict

  1. User visits https://external-site.com
  2. User clicks link to https://shop.example.com/products
  3. Cookie exists: session=abc123; Domain=shop.example.com; SameSite=Strict
  4. Result: Cookie is NOT sent (SameSite=Strict blocks cross-site requests)

Cross-Site POST Requests

The cookie is not sent with cross-site requests that use the POST method, such as when submitting a form on another website.

Definition

Cross-site POST requests do not include cookies, even for top-level navigation, unless the cookie has SameSite=None.

Characteristics

Examples

Scenario 1: Form Submission

  1. User visits https://external-site.com
  2. Form on page: <form method="POST" action="https://shop.example.com/login">
  3. User submits form
  4. Cookie exists: session=abc123; Domain=shop.example.com; SameSite=Lax
  5. Result: Cookie is NOT sent (cross-site POST request)

Scenario 2: AJAX POST

  1. User visits https://external-site.com
  2. JavaScript makes request: fetch('https://shop.example.com/api/data', { method: 'POST' })
  3. Cookie exists: session=abc123; Domain=shop.example.com; SameSite=Lax
  4. Result: Cookie is NOT sent (cross-site POST request, not top-level navigation)

Scenario 3: SameSite=None

  1. User visits https://external-site.com
  2. Form on page: <form method="POST" action="https://shop.example.com/login">
  3. User submits form
  4. Cookie exists: session=abc123; Domain=shop.example.com; SameSite=None; Secure
  5. Result: Cookie IS sent (SameSite=None allows cross-site POST)

Request Type Comparison

Same-Site Requests

Request Type Cookie Sent? Notes
Same domain GET ✅ Yes Default behavior
Same domain POST ✅ Yes Default behavior
Same domain AJAX ✅ Yes Default behavior
Subdomain GET ✅ Yes If Domain attribute allows
Subdomain POST ✅ Yes If Domain attribute allows

Cross-Site Requests

Request Type SameSite=Lax SameSite=Strict SameSite=None
GET Navigation ✅ Yes ❌ No ✅ Yes
POST Form ❌ No ❌ No ✅ Yes
AJAX/Fetch ❌ No ❌ No ✅ Yes
Image/Pixel ❌ No ❌ No ✅ Yes
Iframe ❌ No ❌ No ✅ Yes

Visual Flow Diagrams

Same-Site Request Flow

sequenceDiagram participant User participant Browser participant SiteA as Site A
(example.com) Note over User,SiteA: Cookie set: session=abc#59; Domain=example.com User->>Browser: Navigate to example.com/products Browser->>Browser: Check: Request domain = Cookie domain? Browser->>Browser: ✅ YES - Same-site request Browser->>SiteA: GET /products
Cookie: session=abc SiteA->>Browser: HTTP 200 OK
Content: Products page

Cross-Site GET Request Flow

sequenceDiagram participant User participant Browser participant ExternalSite as External Site
(external.com) participant SiteA as Site A
(example.com) Note over Browser,SiteA: Cookie set: session=abc#59; Domain=example.com#59; SameSite=Lax User->>Browser: Visit external.com Browser->>ExternalSite: GET /page ExternalSite->>Browser: HTML with link to example.com User->>Browser: Click link to example.com Browser->>Browser: Check: Request domain ≠ Cookie domain? Browser->>Browser: ✅ YES - Cross-site request Browser->>Browser: Check: GET navigation + SameSite=Lax? Browser->>Browser: ✅ YES - Send cookie Browser->>SiteA: GET /products
Cookie: session=abc SiteA->>Browser: HTTP 200 OK
Content: Products page

Cross-Site POST Request Flow

sequenceDiagram participant User participant Browser participant ExternalSite as External Site
(external.com) participant SiteA as Site A
(example.com) Note over Browser,SiteA: Cookie set: session=abc#59; Domain=example.com#59; SameSite=Lax User->>Browser: Visit external.com Browser->>ExternalSite: GET /page ExternalSite->>Browser: HTML with POST form to example.com User->>Browser: Submit form to example.com Browser->>Browser: Check: Request domain ≠ Cookie domain? Browser->>Browser: ✅ YES - Cross-site request Browser->>Browser: Check: POST method + SameSite=Lax? Browser->>Browser: ❌ NO - Don't send cookie Browser->>SiteA: POST /login
Cookie: (none) SiteA->>Browser: HTTP 200 OK
Content: Login page

SameSite Attribute Impact

SameSite=Lax (Default in Modern Browsers)

Behavior:

Use Case: Most common setting for authentication cookies. Provides CSRF protection while allowing natural navigation.

SameSite=Strict

Behavior:

Use Case: Maximum security. User must visit site directly or from same-site context.

SameSite=None

Behavior:

Requirements: Must also include Secure attribute (HTTPS only).

Use Case: Third-party cookies for tracking, advertising, embedded widgets.

Testing Scenarios

Test 1: Same-Site Request

  1. Visit https://site-a.cookie-playground.pun7o.click
  2. Set cookie: test=value1; Domain=site-a.cookie-playground.pun7o.click
  3. Navigate to https://site-a.cookie-playground.pun7o.click/index.html
  4. Expected: Cookie is sent (same-site request)

Test 2: Cross-Site GET Navigation

  1. Visit https://site-b.cookie-playground.pun7o.click
  2. Set cookie: test=value2; Domain=site-a.cookie-playground.pun7o.click; SameSite=Lax
  3. Click link from subdomain B to subdomain A
  4. Expected: Cookie is sent (cross-site GET navigation with SameSite=Lax)

Test 3: Cross-Site POST

  1. Visit https://site-b.cookie-playground.pun7o.click
  2. Set cookie: test=value3; Domain=site-a.cookie-playground.pun7o.click; SameSite=Lax
  3. Submit POST form from subdomain B to subdomain A
  4. Expected: Cookie is NOT sent (cross-site POST blocked by SameSite=Lax)

Test 4: Cross-Site Pixel Request

  1. Visit https://site-b.cookie-playground.pun7o.click
  2. Set cookie: test=value4; Domain=site-a.cookie-playground.pun7o.click; SameSite=Lax
  3. Load pixel: <img src="https://site-a.cookie-playground.pun7o.click/pixel">
  4. Expected: Cookie is NOT sent (embedded resource, not top-level navigation)

Key Takeaways

Same-Site Requests

Cross-Site GET Requests

Cross-Site POST Requests

Security Implications