Webbeveiliging

CSRF (cross-site request forgery)

Definitie

CSRF (cross-site request forgery) is een aanval waarbij de browser van een ingelogde gebruiker, zonder dat die het weet, een verzoek verstuurt naar een site waar zijn sessie openstaat. De site denkt aan een bewuste actie: een gewijzigd e-mailadres, een aangepaste instelling of een nieuw account.

CSRF (cross-site request forgery), Webbeveiliging

CSRF maakt misbruik van een automatisme van de browser: bij elk verzoek naar een site stuurt hij de cookies van die site mee, ook de sessiecookie. Een externe pagina kan dus een verzoek naar jouw site laten vertrekken, en de server ontvangt het met de inloggegevens van de ingelogde persoon. Niets onderscheidt het van een bewuste klik, tenzij de site controleert of het verzoek echt uit zijn eigen formulieren komt. MITRE registreert de zwakte als CWE-352; je ziet ook de afkorting XSRF.

Hoe een CSRF-aanval werkt

De aanvaller maakt een pagina met een verzoek naar de doelsite: een onzichtbare afbeelding waarvan de URL een actie start, of een verborgen formulier dat JavaScript automatisch verstuurt. Daarna hoeft hij het slachtoffer alleen nog naar die pagina te lokken, met een link in een e-mail, een reactie of een bericht. Is het slachtoffer op dat moment ingelogd op de doelsite, dan vertrekt het verzoek met zijn sessie.

Verloop van een CSRF-aanval in vijf stappen: de beheerder is ingelogd, hij bezoekt een valstrikpagina, een verborgen formulier gaat met zijn sessiecookie naar de site, de site voert de actie zonder controle uit, terwijl een gecontroleerde nonce het verzoek had laten weigeren
De browser van het slachtoffer doet al het werk: de aanvaller heeft zijn wachtwoord nooit nodig.

Zoals OWASP benadrukt, ziet de aanvaller het antwoord van de server niet. CSRF richt zich dus op verzoeken die iets veranderen: het e-mailadres van een account wijzigen, een instelling aanpassen, een gebruiker aanmaken, inhoud verwijderen. In de beheeromgeving van een WordPress-site zijn zulke acties vaak genoeg om de controle over te nemen.

De rol van SameSite-cookies

Het cookie-attribuut SameSite beperkt het meesturen van cookies vanaf een andere site. Met Strict gaat de cookie alleen mee met verzoeken die van dezelfde site komen; met Lax gaat hij ook mee bij een navigatie op topniveau met een veilige methode, zoals een gewone GET-link. MDN vermeldt dat sommige browsers Lax als standaard toepassen als het attribuut ontbreekt. Dat is een nuttige maar gedeeltelijke bescherming: een actie die via een GET-link wordt gestart, komt er nog door, en niet alle browsers gedragen zich hetzelfde. Het komt dus bovenop anti-CSRF-tokens, zonder ze te vervangen.

Video: “Cross-Site Request Forgery (CSRF) Explained” (PwnFunction, in het Engels)

Voor WordPress: nonces en rechtencontrole

WordPress beschermt zijn formulieren en actielinks met nonces: tokens die gekoppeld zijn aan de gebruiker, zijn sessie en de gevraagde actie, en die een externe site niet kan raden. Ze zijn standaard 24 uur geldig, verdeeld over twee periodes van 12 uur. Een plugin die eigen acties toevoegt, moet ze ook gebruiken:

// In het formulier
wp_nonce_field( 'mijnplugin_opslaan', 'mijnplugin_nonce' );

// Bij de verwerking
check_admin_referer( 'mijnplugin_opslaan', 'mijnplugin_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
    wp_die( 'Toegang geweigerd' );
}
  • wp_nonce_field() en wp_nonce_url() voegen het token toe aan een formulier of een URL;
  • check_admin_referer() controleert het in de beheeromgeving, check_ajax_referer() bij een AJAX-verzoek, wp_verify_nonce() elders;
  • current_user_can() blijft verplicht: de WordPress-documentatie benadrukt dat een nonce niet dient voor authenticatie of toegangscontrole.

Hoe je je als eigenaar beschermt

Vergeten nonces komen in plugins nog vaak voor: CSRF hoort bij de soorten lekken die regelmatig worden gepubliceerd, zoals blijkt uit de cijfers over kwetsbaarheden in WordPress-plugins. Als eigenaar zijn de reflexen eenvoudig: bijwerken, geen onbekende links openen tijdens een beheersessie, uitloggen na je werk en niet te veel beheerdersaccounts aanmaken. Noch WP Masquerade noch een instelling in het Dashboard repareert een ontbrekende nonce in een plugin: alleen een update van die plugin doet dat.

Veelgemaakte fouten

  • De nonce controleren maar de rechten niet: een ingelogde abonnee die een geldige nonce ophaalt uit een pagina die hij mag zien, kan dan een actie aanroepen die voor beheerders bedoeld is. Zo ontstaan lekken van het type IDOR of gebrekkige toegangscontrole.
  • Gegevens wijzigen via een gewoon GET-verzoek, dat zelfs met cookies op SameSite=Lax doorkomt.
  • Vergeten dat een XSS-lek de bescherming tenietdoet: een script dat in de pagina draait, leest de nonces die erin staan.
  • CSRF verwarren met clickjacking: daarbij laat de aanvaller het slachtoffer klikken op je echte pagina, getoond in een onzichtbaar frame, en dat houdt een nonce niet tegen.

Verder lezen

  • Artikel Kwetsbaarheden in WordPress-plugins in cijfers

Bronnen

  1. OWASP: Cross Site Request Forgery (CSRF) (externe link, opent in een nieuw tabblad)
  2. MITRE CWE-352: Cross-Site Request Forgery (CSRF) (externe link, opent in een nieuw tabblad)
  3. WordPress Developer Resources: Nonces (externe link, opent in een nieuw tabblad)
  4. MDN: Set-Cookie, attribut SameSite (externe link, opent in een nieuw tabblad)

Alle definities

WordPress-beveiliging, zonder ruis

Eén e-mail wanneer het ertoe doet: nieuw waargenomen aanvallen, updates van de plugin en praktische gidsen. Geen spam, afmelden met één klik.

Begin gratis, stap over op Pro wanneer je eraan toe bent

De gratis versie verbergt WordPress al en verplaatst de inlogpagina. Pro voegt aliassen, tweestapsverificatie en bewaking toe.