CSRF (Cross-Site Request Forgery)

Securityintermediate

// Definition

An attack that tricks an authenticated user's browser into sending a state-changing request to a site they are logged into, without their knowledge. Because the browser automatically attaches session cookies, the target server sees a legitimate-looking request. Classic mitigations: synchroniser tokens (a server-issued nonce added to forms and verified on submission), SameSite cookie attributes, and checking the Origin or Referer header. From a QA perspective: every state-changing endpoint (POST, PUT, PATCH, DELETE) should require a valid CSRF token or rely on SameSite=Strict/Lax cookies.

// Why it matters

CSRF rides a logged-in user's cookies to perform actions they didn't intend — a malicious page silently POSTs to your app using the victim's session. QA matters because the defence (anti-CSRF tokens, SameSite cookies) is easy to misconfigure and easy to forget to test: the request looks valid because, to the server, it is.

// How to test

// A state-changing request WITHOUT the CSRF token must be rejected
cy.getCookie('session').should('exist')
cy.request({
  method: 'POST',
  url: '/api/account/email',
  body: { email: 'attacker@evil.com' },
  // deliberately omit the X-CSRF-Token header
  failOnStatusCode: false,
}).its('status').should('eq', 403)

// Common mistakes

  • Protecting POST but leaving state-changing GET endpoints open
  • Accepting the token from a place an attacker can set (a query param)
  • Relying on SameSite=Lax alone for top-level POST navigations

// Related terms