乐闻世界logo
搜索文章和话题

What are the principles and implementation methods of Double Submit Cookie for CSRF protection?

2月19日 19:15

Double Submit Cookie is a CSRF protection technique that verifies the legitimacy of requests by storing the same Token in both the Cookie and request parameters.

  1. Token Generation: Server generates a random CSRF Token
  2. Double Storage: Token is stored in both Cookie and request parameters
  3. Verification Logic: Server verifies whether the Token in Cookie matches the Token in request parameters

Implementation Steps

1. Generate Token

javascript
function generateCSRFToken() { return crypto.randomBytes(32).toString('hex'); } // Middleware: Generate and set Token function csrfTokenMiddleware(req, res, next) { const token = generateCSRFToken(); res.cookie('csrfToken', token, { httpOnly: false, // JavaScript needs to read secure: true, sameSite: 'strict' }); res.locals.csrfToken = token; next(); }

2. Include Token in Form

html
<form action="/api/submit" method="POST"> <input type="hidden" name="csrfToken" value="<%= csrfToken %>"> <!-- Other form fields --> <button type="submit">Submit</button> </form> <!-- Or set via JavaScript --> <script> const form = document.querySelector('form'); const csrfToken = document.querySelector('meta[name="csrf-token"]').content; const input = document.createElement('input'); input.type = 'hidden'; input.name = 'csrfToken'; input.value = csrfToken; form.appendChild(input); </script>

3. Verify Token

javascript
function validateDoubleSubmitCookie(req) { const cookieToken = req.cookies.csrfToken; const paramToken = req.body.csrfToken || req.query.csrfToken; if (!cookieToken || !paramToken) { return false; } // Use constant-time comparison to prevent timing attacks return crypto.timingSafeEqual( Buffer.from(cookieToken), Buffer.from(paramToken) ); } // Verification middleware function csrfProtection(req, res, next) { if (req.method === 'GET' || req.method === 'HEAD' || req.method === 'OPTIONS') { return next(); } if (!validateDoubleSubmitCookie(req)) { return res.status(403).send('CSRF token validation failed'); } next(); }

How It Works

Why Double Submission Works?

  1. Same-Origin Policy: Malicious websites cannot read target website's cookies
  2. Cross-site Request Restrictions: Malicious websites cannot include correct Token in request parameters
  3. Match Verification: Only same-origin requests can access both Cookie and set request parameters

Attack Scenario Analysis

html
<!-- Malicious website attempts CSRF attack --> <form action="https://example.com/api/transfer" method="POST"> <input type="hidden" name="to" value="attacker"> <input type="hidden" name="amount" value="1000"> <!-- Cannot obtain correct csrfToken --> </form> <script> document.querySelector('form').submit(); </script>
  • Malicious website can initiate request
  • Browser automatically sends Token from Cookie
  • But malicious website cannot include correct Token in request parameters
  • Server verification fails, request rejected

Advantages

  1. No Server State: No need to store Token on server
  2. Easy to Implement: Relatively simple implementation
  3. Scalability: Suitable for distributed systems
  4. Good Performance: No need to query database or Session

Limitations

  1. Cookie Security:

    • Protection fails if Cookie is stolen (XSS)
    • Need to use with HttpOnly (but JavaScript cannot read)
  2. Subdomain Risk:

    • If subdomain has XSS vulnerability, may affect main domain
    • Need to carefully set Cookie's domain attribute
  3. Token Leakage:

    • If Token is exposed in URL, may be recorded in logs
    • Should use POST request to pass Token

Best Practices

1. Combine with Other Protection Measures

javascript
app.use(helmet()); // XSS protection app.use(cookieSession({ secret: 'secret', cookie: { httpOnly: true, secure: true, sameSite: 'strict' } })); app.use(csrfTokenMiddleware); app.use(csrfProtection);

2. Token Refresh Strategy

javascript
// Refresh Token after each request function refreshTokenMiddleware(req, res, next) { if (req.method !== 'GET' && req.method !== 'HEAD') { const newToken = generateCSRFToken(); res.cookie('csrfToken', newToken, { httpOnly: false, secure: true, sameSite: 'strict' }); res.locals.csrfToken = newToken; } next(); }

3. Security Configuration

javascript
// Cookie configuration res.cookie('csrfToken', token, { httpOnly: false, // Allow JavaScript to read secure: true, // HTTPS only sameSite: 'strict', // Strictest same-site policy maxAge: 3600000, // 1 hour expiration domain: '.example.com' // Carefully set domain });

Comparison with CSRF Token

FeatureDouble Submit CookieTraditional CSRF Token
Server StateNot neededNeeds Session
Implementation ComplexitySimpleMedium
Distributed SupportExcellentNeeds shared Session
SecurityGoodExcellent
PerformanceExcellentGood

Double Submit Cookie is an effective CSRF protection technique, especially suitable for distributed systems and scenarios requiring high performance. But it should be used with other security measures to provide comprehensive security protection.

标签:CSRF