home / skills / secondsky / claude-skills / csrf-protection

This skill helps you implement robust CSRF protection using synchronizer tokens, double-submit cookies, and SameSite attributes across web forms.

npx playbooks add skill secondsky/claude-skills --skill csrf-protection

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
2.3 KB
---
name: csrf-protection
description: Implements CSRF protection using synchronizer tokens, double-submit cookies, and SameSite attributes. Use when securing web forms, protecting state-changing endpoints, or implementing defense-in-depth authentication.
---

# CSRF Protection

Defend against Cross-Site Request Forgery attacks using multiple protection layers.

## Protection Methods

| Method | How It Works | Browser Support |
|--------|--------------|-----------------|
| Synchronizer Token | Hidden form field validated server-side | All |
| Double Submit | Cookie + header must match | All |
| SameSite Cookie | Browser blocks cross-origin requests | Modern |

## Token-Based Protection (Express)

```javascript
const crypto = require('crypto');

function generateToken() {
  return crypto.randomBytes(32).toString('hex');
}

// Middleware
app.use((req, res, next) => {
  if (!req.session.csrfToken) {
    req.session.csrfToken = generateToken();
  }
  res.locals.csrfToken = req.session.csrfToken;
  next();
});

// Validation
app.post('*', (req, res, next) => {
  const token = req.body._csrf || req.headers['x-csrf-token'];
  if (!token || !crypto.timingSafeEqual(
    Buffer.from(token),
    Buffer.from(req.session.csrfToken)
  )) {
    return res.status(403).json({ error: 'Invalid CSRF token' });
  }
  next();
});
```

## SameSite Cookies

```javascript
app.use(session({
  cookie: {
    httpOnly: true,
    secure: true,
    sameSite: 'strict', // or 'lax'
    maxAge: 3600000
  }
}));
```

## HTML Form Integration

```html
<form method="POST" action="/transfer">
  <input type="hidden" name="_csrf" value="<%= csrfToken %>">
  <button type="submit">Submit</button>
</form>
```

## Best Practices

- Apply to all state-changing requests (POST, PUT, DELETE)
- Use SameSite=Strict for sensitive cookies
- Validate Origin/Referer headers
- Never use GET for modifications
- Implement token expiration (1 hour typical)
- Combine multiple defense layers

## Additional Implementations

See [references/python-react.md](references/python-react.md) for:
- Flask-WTF complete CSRF setup
- React hooks for CSRF token management
- Double submit cookie pattern

## Common Mistakes

- Assuming authentication prevents CSRF
- Reusing tokens across sessions
- Storing tokens in localStorage
- Missing token expiration

Overview

This skill implements multi-layer CSRF protection for TypeScript web apps using synchronizer tokens, double-submit cookies, and SameSite cookie attributes. It provides middleware and integration patterns for server-side token generation/validation, secure session cookies, and client form/header workflows to stop cross-site request forgery. Use it to add production-ready, defense-in-depth CSRF controls to state-changing endpoints.

How this skill works

The skill generates cryptographically strong per-session tokens and exposes them to templates or client code. On requests that modify state, middleware validates a token from a hidden form field or X-CSRF-Token header using timing-safe comparison. It also supports the double-submit pattern where a cookie and a header must match, and configures cookies with SameSite, HttpOnly, and Secure flags to reduce cross-origin exposure.

When to use it

  • Protecting POST/PUT/DELETE endpoints that change server state
  • Securing web forms and AJAX state-changing requests
  • Defending sensitive flows like account changes and payments
  • Adding defense-in-depth alongside authentication and CORS
  • When browser clients and server sessions are both present

Best practices

  • Apply protection to all state-changing routes and methods
  • Use per-session tokens and rotate/expire tokens (e.g., 1 hour)
  • Prefer SameSite=Strict or Lax on session cookies for sensitive apps
  • Validate Origin or Referer headers in addition to tokens
  • Avoid storing tokens in localStorage; expose via template or secure cookie
  • Use timing-safe comparisons to compare tokens to prevent leaks

Example use cases

  • Express app: middleware that injects a session CSRF token into templates and validates POST requests
  • Single-page apps: issue a cookie token and require X-CSRF-Token header on fetch requests (double-submit)
  • Payment or transfer forms: include a hidden _csrf field rendered from res.locals.csrfToken
  • APIs behind browser clients: combine SameSite cookies with Origin checks for defense-in-depth
  • Migration from insecure patterns: replace GET-based state changes with CSRF-protected POST endpoints

FAQ

Do I need CSRF protection if I use authentication?

Yes. Authentication alone doesn't prevent CSRF because browsers will send credentials (cookies) automatically; tokens or SameSite controls are required.

When should I use double-submit vs synchronizer tokens?

Use synchronizer tokens when you control server sessions and templates. Double-submit is useful for stateless or SPA scenarios where a cookie and header comparison is simpler.