HTTP

Cookie Attribute

Path

Learn how the Path cookie attribute restricts which URL paths can receive cookies. Understand path matching rules and how to scope cookies to specific routes.

5 min read beginner Try in Playground

TL;DR: Restricts which URL paths receive the cookie (e.g., Path=/admin only sends to admin pages) - use to scope cookies to specific app sections and reduce unnecessary cookie transmission.

What is the Path Attribute?

The Path attribute controls which URL paths can receive a cookie. It’s like setting delivery instructions for mail - “only deliver to apartments on the 3rd floor.” Without this attribute, cookies are sent to all paths on the domain, which can be inefficient and potentially insecure.

This attribute helps scope cookies to specific sections of your application.

How It Works

No Path Attribute (Default)

Cookie sent to all paths on the domain:

Set-Cookie: userData=john123
# From: /shop/cart
# Sent to: /, /shop, /shop/cart, /admin, /api, etc.
```text

### With Path Attribute

Cookie only sent to matching paths:

```http
Set-Cookie: adminToken=xyz789; Path=/admin
# From: /admin/dashboard
# Sent to: /admin, /admin/dashboard, /admin/users
# Not sent to: /, /shop, /api

Path Matching Rules

Exact Path and Subdirectories

Set-Cookie: data=value; Path=/shop
```text

**Sent to:**

- `/shop` ✅
- `/shop/` ✅
- `/shop/cart` ✅
- `/shop/checkout/payment` ✅

**Not sent to:**

- `/` ❌
- `/api` ❌
- `/shopping` ❌ (different path)
- `/admin` ❌

### Root Path

```http
Set-Cookie: globalData=value; Path=/

Sent to all paths:

  • /
  • /shop
  • /admin
  • /api/users

Specific Subdirectory

Set-Cookie: apiKey=secret; Path=/api/v1
```text

**Sent to:**

- `/api/v1` ✅
- `/api/v1/` ✅
- `/api/v1/users` ✅
- `/api/v1/orders/123` ✅

**Not sent to:**

- `/api` ❌
- `/api/v2` ❌
- `/shop` ❌

## Real-World Examples

### Admin Panel Security

Restrict admin cookies to admin paths:

```http
Set-Cookie: adminSession=secure123; Path=/admin; HttpOnly; Secure; Max-Age=3600

Admin cookies never sent to public pages, reducing exposure.

API Authentication

Scope API tokens to API endpoints:

Set-Cookie: apiToken=bearer456; Path=/api; HttpOnly; Secure; SameSite=Strict
```text

### Shopping Cart

Keep cart data in shopping section:

```http
Set-Cookie: cartId=cart789; Path=/shop; Max-Age=604800; SameSite=Lax

User Dashboard

Personal data only in user area:

Set-Cookie: userPrefs=theme:dark; Path=/dashboard; Max-Age=2592000
```text

### Multi-Tenant Applications

Separate tenant data by path:

```http
Set-Cookie: tenantId=acme; Path=/tenants/acme; Secure
Set-Cookie: tenantId=corp; Path=/tenants/corp; Secure

Development vs Production APIs

# Development API
Set-Cookie: devToken=dev123; Path=/dev/api; Max-Age=86400

# Production API
Set-Cookie: prodToken=prod456; Path=/api; Max-Age=3600
```text

## Security Benefits

### Principle of Least Privilege

Only send cookies where needed:

```http
# ❌ Overly broad: Admin token sent everywhere
Set-Cookie: adminToken=secret; HttpOnly; Secure

# ✅ Properly scoped: Admin token only in admin area
Set-Cookie: adminToken=secret; Path=/admin; HttpOnly; Secure

Reduced Attack Surface

# Admin cookie not exposed to public pages
Set-Cookie: adminSession=xyz; Path=/admin; HttpOnly; Secure

# Public pages can't access admin cookies
# Reduces risk if public pages have XSS vulnerabilities
```http

### Data Isolation

```http
# Different user types get different cookies
Set-Cookie: customerData=abc; Path=/customer; HttpOnly
Set-Cookie: employeeData=def; Path=/employee; HttpOnly
Set-Cookie: adminData=ghi; Path=/admin; HttpOnly

Implementation Examples

Express.js

// Admin routes
app.use('/admin', (req, res, next) => {
  // Admin-specific cookie
  res.cookie('adminContext', 'true', {
    path: '/admin',
    httpOnly: true,
    secure: true,
    maxAge: 2 * 60 * 60 * 1000 // 2 hours
  })
  next()
})

// API routes
app.use('/api', (req, res, next) => {
  // API-specific cookie
  res.cookie('apiVersion', 'v2', {
    path: '/api',
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
  })
  next()
})

// Shopping cart
app.post('/shop/add-to-cart', (req, res) => {
  res.cookie('cartId', generateCartId(), {
    path: '/shop',
    maxAge: 7 * 24 * 60 * 60 * 1000, // 1 week
    sameSite: 'lax'
  })
})
```text

### Python Flask

```python
@app.route('/admin/login', methods=['POST'])
def admin_login():
    session_id = generate_admin_session()

    response = make_response({'success': True})
    response.set_cookie(
        'adminSession',
        session_id,
        path='/admin',
        httponly=True,
        secure=True,
        max_age=7200  # 2 hours
    )

    return response

PHP

// Admin area cookie
if (strpos($_SERVER['REQUEST_URI'], '/admin') === 0) {
    setcookie('adminToken', $token, [
        'expires' => time() + 3600,
        'path' => '/admin',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'Strict'
    ]);
}
```text

## Best Practices

**1. Use specific paths for sensitive cookies:**

```http
 Set-Cookie: adminToken=secret; Path=/admin; HttpOnly; Secure
 Set-Cookie: adminToken=secret; HttpOnly; Secure

2. Match cookie path to application structure:

/api/v1     → Path=/api/v1
/admin      → Path=/admin
/user       → Path=/user
/shop       → Path=/shop

3. Use root path sparingly:

# Only for truly global data
Set-Cookie: siteTheme=dark; Path=/; Max-Age=31536000

# Not for sensitive data
❌ Set-Cookie: sessionId=secret; Path=/
✅ Set-Cookie: sessionId=secret; Path=/app; HttpOnly
```text

**4. Consider cookie cleanup:**

```javascript
// Clear cookies from specific paths
app.post('/logout', (req, res) => {
  // Clear admin cookies
  res.clearCookie('adminSession', { path: '/admin' })

  // Clear user cookies
  res.clearCookie('userSession', { path: '/user' })

  // Clear global cookies
  res.clearCookie('globalPrefs', { path: '/' })
})

5. Document path strategy:

// Cookie path strategy:
// /admin/* - Admin-only cookies (sessions, permissions)
// /api/*   - API-specific cookies (tokens, rate limits)
// /shop/*  - Shopping-related cookies (cart, preferences)
// /*       - Global cookies (theme, language)

const COOKIE_PATHS = {
  ADMIN: '/admin',
  API: '/api',
  SHOP: '/shop',
  GLOBAL: '/'
}
```javascript

## Common Patterns

### Hierarchical Permissions

```javascript
// Different access levels with different paths
const setUserCookie = (level, sessionId) => {
  const paths = {
    admin: '/admin',
    manager: '/manager',
    user: '/user',
    public: '/'
  }

  res.cookie('sessionId', sessionId, {
    path: paths[level],
    httpOnly: true,
    secure: true
  })
}

API Versioning

// Different cookies for different API versions
app.use('/api/v1', (req, res, next) => {
  res.cookie('apiVersion', 'v1', { path: '/api/v1' })
  next()
})

app.use('/api/v2', (req, res, next) => {
  res.cookie('apiVersion', 'v2', { path: '/api/v2' })
  next()
})
```javascript

### Feature Flags by Section

```javascript
// Different features enabled in different sections
const featureFlags = {
  '/beta': { newUI: true, advancedFeatures: true },
  '/stable': { newUI: false, advancedFeatures: false }
}

app.use('/beta', (req, res, next) => {
  res.cookie('features', JSON.stringify(featureFlags['/beta']), {
    path: '/beta'
  })
  next()
})

Troubleshooting

// Problem: Path doesn't match request URL
Set-Cookie: data=value; Path=/admin
// Request to: /shop/cart (no match)

// Solution: Check path matching
console.log('Request path:', req.path)
console.log('Cookie path:', '/admin')
console.log('Matches:', req.path.startsWith('/admin'))
```text

### Cookie Sent to Wrong Paths

```javascript
// Problem: No path restriction
Set-Cookie: adminToken=secret  // Sent everywhere!

// Solution: Add appropriate path
Set-Cookie: adminToken=secret; Path=/admin

Path Case Sensitivity

// Problem: Case mismatch
Set-Cookie: data=value; Path=/Admin
// Request to: /admin (lowercase)

// Solution: Use consistent casing (usually lowercase)
Set-Cookie: data=value; Path=/admin
  • Domain - Controls domain access
  • Secure - HTTPS-only transmission
  • HttpOnly - Prevent JavaScript access
  • SameSite - Cross-site request control

Frequently Asked Questions

What is the Path cookie attribute?

Path restricts which URL paths receive the cookie. A cookie with Path=/admin is only sent to URLs starting with /admin. Default is the current path.

How does Path matching work?

Path uses prefix matching. Path=/docs matches /docs, /docs/api, /docs/guide. It does not match /documents because that is a different prefix.

Should I always set Path?

Set Path=/ for site-wide cookies. Use specific paths only when you need to restrict cookie scope, like admin-only cookies with Path=/admin.

Is Path a security feature?

No, Path is not a security boundary. JavaScript on any path can read cookies for other paths on the same origin. Use it for organization, not security.

Keep Learning