Webbeveiliging

Nonce

Definitie

Een nonce is een waarde, in principe willekeurig en eenmalig, die aan een uitwisseling wordt toegevoegd om te voorkomen dat die wordt herhaald of vervalst. In WordPress is de nonce een token dat gekoppeld is aan een actie, een gebruiker en zijn sessie, 12 tot 24 uur geldig, en dat vooral beschermt tegen CSRF-aanvallen.

Nonce, Webbeveiliging

Het woord komt van het Engelse "number used once". In de cryptografie omschrijft MDN het als een willekeurige waarde die maar een keer in een communicatie wordt gebruikt, om te voorkomen dat een onderschept bericht opnieuw wordt afgespeeld, om te garanderen dat een antwoord vers is of om toeval toe te voegen aan een berekening. Op het web dekt de term echter twee nogal verschillende zaken, die je beter niet door elkaar haalt: de "zuivere" cryptografische nonce en de nonce van WordPress.

Waar nonces op het web voor dienen

  • In protocollen: de uitwisselingen van TLS en veel authenticatiemechanismen bevatten eenmalige willekeurige waarden, zodat een opgenomen gesprek niet ongewijzigd kan worden afgespeeld.
  • In een Content Security Policy: de server maakt bij elk antwoord een willekeurige waarde aan en zet die in de directive script-src 'nonce-...' en in het attribuut nonce van de toegestane scripts. Een strikte CSP voert alleen scripts uit die de juiste waarde dragen. MDN benadrukt dat die waarde bij elk antwoord moet veranderen en onvoorspelbaar moet blijven.
  • Tegen vervalste verzoeken: een geheim token in formulieren bewijst dat het verzoek echt van een pagina van de site komt, wat CSRF-aanvallen tegenhoudt. Dat is de belangrijkste rol van WordPress-nonces.

WordPress-nonces: niet echt nonces

De officiële documentatie van WordPress geeft het zelf toe: zijn nonces zijn geen getallen en ook niet eenmalig. De functie wp_create_nonce() berekent een hash van tien tekens op basis van de gevraagde actie, het ID van de gebruiker, zijn sessietoken en een tijdsperiode. Daarbij worden de sleutels NONCE_KEY en NONCE_SALT uit wp-config.php gebruikt, en daarom is een unieke salt belangrijk.

  • Levensduur: standaard een dag, verdeeld in twee periodes van 12 uur. Afhankelijk van het moment waarop hij is aangemaakt, blijft een nonce dus 12 tot 24 uur geldig. Het filter nonce_life past die duur aan.
  • Herbruikbaar: WordPress controleert niet of een nonce maar een keer is gebruikt. Binnen de geldigheidsduur beschermt hij dus niet tegen herhaling.
  • Niet-ingelogde bezoekers: hun ID is 0, waardoor alle anonieme bezoekers voor dezelfde actie dezelfde nonce kunnen krijgen.
Schema in vijf stappen: WordPress maakt een nonce gekoppeld aan de actie, de gebruiker, zijn sessie en een periode van 12 uur; de gebruiker verstuurt het formulier met het token; een vervalst verzoek vanaf een andere site komt aan zonder het juiste token; check_admin_referer of wp_verify_nonce weigert het; current_user_can controleert ten slotte de capability voordat er iets gebeurt
De nonce bewijst dat het verzoek van een pagina van de site komt; de rechten worden apart gecontroleerd.

Voor WordPress: nonces goed gebruiken

Voor een ontwikkelaar van thema's of plugins komt de regel neer op drie functies en een rechtencontrole:

// In het formulier
wp_nonce_field( 'verwijder_post_' . $post_id );

// Bij de verwerking
check_admin_referer( 'verwijder_post_' . $post_id );
if ( ! current_user_can( 'delete_post', $post_id ) ) {
    wp_die( 'Actie niet toegestaan.' );
}
  • check_admin_referer() controleert de nonce en de referer op beheerschermen, check_ajax_referer() alleen de nonce voor AJAX-verzoeken, wp_verify_nonce() in de overige gevallen.
  • Geef de actie een precieze naam (met het ID van het object) in plaats van een algemene naam die de hele site deelt.
  • Vertrouw voor autorisatie nooit op de nonce: de documentatie vraagt om elke functie te beschermen met current_user_can().

Veelgemaakte fouten

Een flink deel van de pluginlekken die elk jaar worden gemeld, komt door een ontbrekende nonce of een vergeten capability-controle, zoals ons artikel over WordPress-pluginlekken in cijfers laat zien. Het typische geval: een AJAX-actie controleert de nonce, maar niet het recht van de gebruiker. Een nonce kan echter uitlekken in de code van een openbare pagina; is hij de enige drempel, dan kan een gewone abonnee soms een beheerdersactie uitvoeren, wat leidt tot privilege-escalatie. Onze gids over rollen en capabilities in WordPress legt het principe van minimale rechten uit.

Nog een valkuil: een pagina die langer dan 12 tot 24 uur in de cache staat, serveert een verlopen nonce, en het formulier mislukt dan met de melding dat de gevolgde link verlopen is (in het Engels "The link you followed has expired"). Sluit pagina's met formulieren voor ingelogde gebruikers uit van de cache.

Verder lezen

  • Artikel Kwetsbaarheden in WordPress-plugins in cijfers

Bronnen

  1. WordPress Common APIs Handbook: Nonces (externe link, opent in een nieuw tabblad)
  2. WordPress Developer Resources: wp_create_nonce() (externe link, opent in een nieuw tabblad)
  3. MDN: Nonce (glossaire) (externe link, opent in een nieuw tabblad)
  4. OWASP: Cross-Site Request Forgery Prevention Cheat Sheet (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.