Skip to content
intermediatePhase 41 · Frontend Security

Secure Cookies

Configure cookies with Secure, HttpOnly, SameSite, and Path attributes.

30m
0 problems
Topic Progress0%

Cookie Attributes

Cookie Attributes

HttpOnly

// Prevents JavaScript access
res.cookie('session', token, {
  httpOnly: true, // Cannot be accessed via document.cookie
});

// JavaScript cannot access
// document.cookie won't show httpOnly cookies

Secure

// Only sent over HTTPS
res.cookie('session', token, {
  secure: true, // Only sent on HTTPS
});

// In development (HTTP)
res.cookie('session', token, {
  secure: process.env.NODE_ENV === 'production',
});

SameSite

// Controls cross-site cookie sending
res.cookie('session', token, {
  sameSite: 'strict', // Only same-site
  sameSite: 'lax',    // Top-level navigation
  sameSite: 'none',   // All (requires secure)
});

// SameSite values:
// strict: Cookie only sent when navigating to same site
// lax: Cookie sent for top-level GET navigations
// none: Cookie sent for all requests (must be secure)

Path and Domain

res.cookie('session', token, {
  path: '/',        // Available for all paths
  domain: '.example.com', // Available for subdomains
});

Expiration

// Session cookie (no expiration)
res.cookie('session', token);

// Persistent cookie
res.cookie('session', token, {
  maxAge: 24 * 60 * 60 * 1000, // 24 hours
  expires: new Date(Date.now() + 86400000), // 24 hours
});

Complete Secure Cookie

res.cookie('session', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 24 * 60 * 60 * 1000,
  path: '/',
});

Cookie Security

Cookie Security

Preventing Theft

// 1. HttpOnly prevents XSS theft
res.cookie('session', token, { httpOnly: true });

// 2. Secure prevents network interception
res.cookie('session', token, { secure: true });

// 3. SameSite prevents CSRF
res.cookie('session', token, { sameSite: 'strict' });

// 4. Short expiration limits exposure
res.cookie('session', token, {
  maxAge: 15 * 60 * 1000, // 15 minutes
});

Session vs Persistent

// Session cookie (deleted when browser closes)
res.cookie('session', token);

// Persistent cookie (survives browser restart)
res.cookie('remember', token, {
  maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
});

// Clear cookie
res.clearCookie('session');
res.clearCookie('session', { path: '/' });

Cookie Prefixes

// Use __Host- prefix for host-only cookies
res.cookie('__Host-session', token, {
  secure: true,
  path: '/',
  httpOnly: true,
});

// Use __Secure- prefix for secure cookies
res.cookie('__Secure-session', token, {
  secure: true,
  httpOnly: true,
});

Best Practices

  1. Always use HttpOnly for sensitive data
  2. Always use Secure in production
  3. Use SameSite: strict or lax
  4. Set short expiration for session cookies
  5. Use cookie prefixes (__Host-, __Secure-)
  6. Don't store sensitive data in cookies
  7. Use HTTPS everywhere
  8. Clear cookies on logout

Common Mistakes

// Bad: Storing sensitive data
res.cookie('user', JSON.stringify({ id: 1, password: 'hashed' }));

// Good: Store only session ID
res.cookie('session', sessionId, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
});

// Bad: Long expiration
res.cookie('session', token, { maxAge: 365 * 24 * 60 * 60 * 1000 });

// Good: Short expiration for sensitive cookies
res.cookie('session', token, { maxAge: 15 * 60 * 1000 });

Cookie Implementation

Cookie Implementation

Express Configuration

import express from 'express';
import cookieParser from 'cookie-parser';

const app = express();
app.use(cookieParser());

// Session cookie
app.post('/login', (req, res) => {
  const token = generateToken(user);
  
  res.cookie('session', token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    maxAge: 15 * 60 * 1000, // 15 minutes
  });

  res.json({ success: true });
});

// Clear cookie on logout
app.post('/logout', (req, res) => {
  res.clearCookie('session', {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    path: '/',
  });

  res.json({ success: true });
});

Frontend Cookie Handling

// Read cookie (only non-httpOnly)
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}

// Cookie cannot be set via JavaScript (httpOnly)
// Must be set via Set-Cookie header

Testing Cookie Security

describe('Cookie Security', () => {
  it('should set secure cookie attributes', async () => {
    const response = await request(app)
      .post('/login')
      .send({ email: 'test@example.com', password: 'password' });

    const cookies = response.headers['set-cookie'];
    expect(cookies).toBeDefined();
    
    const sessionCookie = cookies.find(c => c.startsWith('session='));
    expect(sessionCookie).toContain('HttpOnly');
    expect(sessionCookie).toContain('Secure');
    expect(sessionCookie).toContain('SameSite=Strict');
  });

  it('should clear cookie on logout', async () => {
    const response = await request(app)
      .post('/logout')
      .set('Cookie', 'session=token');

    const cookies = response.headers['set-cookie'];
    expect(cookies).toBeDefined();
    
    const sessionCookie = cookies.find(c => c.startsWith('session='));
    expect(sessionCookie).toContain('Max-Age=0');
  });
});

Cookie Security Headers

// Additional security headers
app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self';"
  );
  next();
});

Practice Problems

0/3solved
Build Secure Cookies Component

Create a reusable React component implementing Secure Cookies. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Secure Cookies Testing

Write unit and integration tests for Secure Cookies using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Secure Cookies Performance

Optimize Secure Cookies for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What does HttpOnly do?

Question 1 options

2. What does SameSite=strict do?

Question 2 options

3. What is the primary purpose of Secure Cookies?

Question 3 options

4. What is a common mistake when implementing Secure Cookies?

Question 4 options

Flashcards

Question

What is HttpOnly?

Answer

A cookie attribute that prevents JavaScript access, protecting against XSS theft.

Question

What is Secure attribute?

Answer

Only sends cookie over HTTPS, preventing network interception.

Question

What are cookie prefixes?

Answer

__Host- and __Secure- prefixes that enforce security attributes.

Question

Why clear cookies on logout?

Answer

To invalidate the session and prevent unauthorized access.

Question

What is Secure Cookies?

Answer

Secure Cookies is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.HttpOnly prevents XSS cookie theft
  • 2.Secure ensures HTTPS-only transmission
  • 3.SameSite prevents CSRF attacks
  • 4.Use short expiration for session cookies
  • 5.Clear cookies on logout

Interview Tips

  • Explain each cookie security attribute
  • Discuss session vs persistent cookies
  • Know how to configure secure cookies

Cheat Sheet

Secure Cookies Cheat Sheet

Attributes

  • HttpOnly: No JavaScript access
  • Secure: HTTPS only
  • SameSite: strict/lax/none
  • Path: Cookie scope
  • MaxAge: Expiration

Best Practices

  • Always use HttpOnly for sensitive data
  • Always use Secure in production
  • Use SameSite: strict or lax
  • Short expiration (15 min for sessions)
  • Use cookie prefixes (__Host-, __Secure-)

Example

res.cookie('session', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 15 * 60 * 1000,
});

Clear Cookie

res.clearCookie('session', { path: '/' });