Slide 1

Slide 1 text

Modern Approaches to Web Security: Stateless CSRF Protection Explained @nicolasgrekas

Slide 2

Slide 2 text

CSRF Introduction Cross-Site Request Forgery

Slide 3

Slide 3 text

Social Engineering User is logged on legitimate bank.com account User opens adversary bang.com without noticing

Slide 4

Slide 4 text

Slide 5

Slide 5 text

bank.com Session cookie sent to bank.com Transfer accepted

Slide 6

Slide 6 text

The Ideal CSRF Protection is Standalone Robust Transparent Cacheable and mandates no JS

Slide 7

Slide 7 text

Check the "Origin" header

Slide 8

Slide 8 text

RFC 6454 Origin: https://bang.com/ Browsers send them automatically That's all what bank.com ​needs

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

RFC 6454 Cacheable, mandates no JS Requires the app to know its own origin => trusted proxy headers FTW / RTFM Use CORS headers for cross-domain needs

Slide 11

Slide 11 text

A browser bug could compromise security protections. Mixing many strategies adds additional layers of defense and gives us more control over security of the application.

Slide 12

Slide 12 text

CSRF Protection OWASP Cheat Sheet Series

Slide 13

Slide 13 text

TL;DR Stateful apps should use session tokens Stateless apps should use double-submit cookies Implement defense-in-depth mitigations Ask some user credentials for sensitive operations Do not use GET requests for state changing operations, or protect them against CSRF

Slide 14

Slide 14 text

Cross-Site Scripting (XSS) or a Man-In-The-Middle (MITM) can defeat all CSRF mitigations!

Slide 15

Slide 15 text

Slide 16

Slide 16 text

Slide 17

Slide 17 text

Session Tokens Caveats Session cookie means page is not-cacheable (Not even login pages) Tokens are a target for attacks Regeneration mandatory at key steps (logins, expiry) Vulnerable to BREACH ​attacks Token rotation means usability concerns (e.g. broken form sumissions or "Back" buttons)

Slide 18

Slide 18 text

Session Tokens Improvements Session cookie means page is not-cacheable window.fetch() to populate the token (PR #54705) Tokens are a target for attacks Regeneration mandatory at key steps (logins, expiry) Always-random part against BREACH ​attacks Token rotation means usability concerns

Slide 19

Slide 19 text

Double-Submit Cookie Pattern No server-side state

Slide 20

Slide 20 text

Slide 21

Slide 21 text

Naive? Discouraged? Cookie fixation Subdomains handling "secure" cookies set from MITMed HTTP => Generate a new token every time in JS

Slide 22

Slide 22 text

Defense In Depth Use HSTS Use "SameSite" attribute for the session cookie Prefix cookie names with "__Host-" Use a custom HTTP header instead of cookie Check the "Origin" header

Slide 23

Slide 23 text

The Ideal CSRF Protection is leveraging Symfony

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Origin Check the Origin header Covers 97% of end users Cacheable No JS

Slide 30

Slide 30 text

Cookie Check the double-submitted Cookie header Implements all security-in-depth mitigations Safe to race-conditions Cacheable Requires JS – snippet shipped as a UX recipe

Slide 31

Slide 31 text

Header Check the double-submitted csrf-token header Not enabled by default Compatible with cookie-clearing reverse proxies Cacheable Requires JS – snippet shipped as a UX recipe

Slide 32

Slide 32 text

Session Check the previously successful strategies Still stateless because opportunistic

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

Can you break it?

Slide 35

Slide 35 text

Be Happy with Symfony! @nicolasgrekas