WordPress nonces prevent CSRF attacks. Every form submission, AJAX call, and admin action that modifies data must verify a nonce before processing. [CWE-352 · A01:2021]
Why This Matters
prevents cross-site request forgery enabling unauthorized settings changes and data modification
Impact: CRITICAL (prevents cross-site request forgery enabling unauthorized settings changes and data modification)
WordPress nonces are time-limited tokens that verify a request originated from your site, not a malicious third-party page. Without nonce verification, an attacker can craft a page that submits forms or triggers actions on behalf of a logged-in WordPress admin who visits the attacker's site.
Every form handler, admin action, and AJAX callback that modifies data must:
Generate a nonce in the form/request
Verify the nonce before processing
Also check current_user_can() — nonces alone don't verify authorization
Incorrect (no nonce verification):
// ❌ Form handler with no CSRF protectionadd_action( 'admin_post_save_settings', function() { update_option( 'my_plugin_api_key', $_POST['api_key'] ); wp_redirect( admin_url( 'options-general.php?page=my-plugin' ) ); exit;});// ❌ Checking nonce exists but not verifying its valueadd_action( 'admin_post_delete_item', function() { if ( isset( $_POST['_wpnonce'] ) ) { // Still vulnerable! Never verified the nonce value wp_delete_post( $_POST['post_id'], true ); }});// ❌ Nonce verified but no capability check — any logged-in user can trigger thisadd_action( 'admin_post_promote_user', function() { check_admin_referer( 'promote_user_nonce' ); // Missing: current_user_can() check! wp_update_user([ 'ID' => $_POST['user_id'], 'role' => 'administrator' ]);});