iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Examples

Worked examples of CSRF defences across the common stacks — Laravel, Express, Rails, Django, Spring — paired with their failure modes. Use them as the reference for what \"good\" looks like in a code review.

Defensive CSRF examples in five frameworks

EXAMPLE
// ============ Laravel ============
// 1) The 'web' middleware group includes VerifyCsrfToken automatically.
// 2) Blade forms emit the hidden token with @csrf.
<form method='POST' action='/account/email'>
  @csrf
  <input name='email' type='email'>
  <button>Update</button>
</form>
// 3) AJAX: read XSRF-TOKEN cookie, send as X-XSRF-TOKEN header
//    Laravel's axios bootstrap already does this.

// ============ Express (Node) ============
// npm i csurf cookie-parser
// import express from 'express'; import csurf from 'csurf';
// const app = express();
// app.use(cookieParser());
// const csrfProtection = csurf({ cookie: { sameSite: 'lax', httpOnly: true, secure: true } });
// app.use(csrfProtection);
// app.get('/form', (req, res) => res.render('form', { csrfToken: req.csrfToken() }));
// app.post('/submit', (req, res) => res.send('ok'));   // automatic check

// ============ Rails ============
// ApplicationController inherits 'protect_from_forgery with: :exception'.
// form_with / form_for embed the authenticity_token hidden field.
// API-only apps:
// class Api::OrdersController < ApplicationController
//   protect_from_forgery with: :null_session  # disables redirect, raises
// end
// Header-based mode: send X-CSRF-Token from JS:
//   const token = document.querySelector('meta[name="csrf-token"]').content;
//   fetch('/orders', { method: 'POST', headers: { 'X-CSRF-Token': token } });

// ============ Django ============
// settings.py: 'django.middleware.csrf.CsrfViewMiddleware' is on by default.
// In templates: {% csrf_token %} inside <form>.
// Class-based views: inherit CsrfMixin / decorate with @csrf_protect.
// AJAX:
//   const cookie = document.cookie.match(/csrftoken=([^;]+)/)[1];
//   await fetch('/api/orders/', { method: 'POST', headers: { 'X-CSRFToken': cookie } });

// ============ Spring (Java) ============
// Spring Security enables CSRF for stateful apps by default.
// @Configuration
// public class WebSecurity {
//   @Bean SecurityFilterChain chain(HttpSecurity http) throws Exception {
//     return http.csrf(c -> c.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
//                             .ignoringRequestMatchers('/webhooks/**'))
//                .build();
//   }
// }
// Thymeleaf forms auto-inject _csrf token.
// SPA frontends read XSRF-TOKEN cookie, send X-XSRF-TOKEN header.

// ============ Same-site cookies — ALWAYS on, regardless of stack ============
// Laravel:  config/session.php -> 'same_site' => 'lax', 'secure' => true
// Express:  res.cookie('sid', sid, { sameSite: 'lax', secure: true, httpOnly: true });
// Rails:    config.session_store :cookie_store, same_site: :lax, secure: true
// Django:   SESSION_COOKIE_SAMESITE = 'Lax'; SESSION_COOKIE_SECURE = True
// Spring:   server.servlet.session.cookie.same-site=lax  + secure=true

Why it matters

For pure-JSON APIs authenticated by a bearer header (Authorization), CSRF is largely a non-issue — browsers refuse to attach a custom header on a cross-origin form submission. The CSRF defences above matter most for cookie-authenticated state-changing endpoints (the most common shape of a server-rendered app).

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Audit a feature end-to-end: HTML form → AJAX call → SPA mutation.
// Confirm SameSite + token + Origin checks at every layer.
Try it Yourself »

Discussion

Loading…