CSRF (Cross-Site Request Forgery)
An attacker tricks a logged-in user's browser into submitting a form on your site. The session cookie rides along; without a separate token, the request looks legitimate. Arcis ships double-submit cookie + HMAC, with constant-time comparison.
What it catches
- Missing CSRF token on state-changing requests (POST, PUT, PATCH, DELETE)
- Token in cookie not matching token in header / body field (the double-submit check)
- Invalid HMAC signature on the token
- Expired token (configurable TTL)
Sample interaction
// Server sends: Set-Cookie: arcis-csrf=<token>; SameSite=Strict
// Client must send back the same token in X-CSRF-Token header on every state-changing call:
POST /api/transfer
Cookie: arcis-csrf=abc.def
X-CSRF-Token: abc.def
Content-Type: application/json
{ "to": "alice", "amount": 100 }
// Without the matching header: 403, vector=csrf, rule=csrf.missing-token
Configuration
import { csrfProtection } from '@arcis/node';
app.use(csrfProtection({
cookieName: 'arcis-csrf',
headerName: 'X-CSRF-Token',
secret: process.env.ARCIS_CSRF_SECRET, // HMAC key
tokenTtl: 3600, // seconds
useHostPrefix: true, // __Host- cookie prefix
skipCsrf: (req) => req.path.startsWith('/api/webhook/'),
}));
Disable on specific routes
// Webhook endpoints typically need CSRF skipped (the signing party is not a browser)
app.use(csrfProtection({
skipCsrf: (req) => req.path.startsWith('/api/webhook/'),
}));