What Is a Nonce in WordPress, and Why Do Forms Need One?
How Nonces Protect Against CSRF
Without this protection, a malicious website could craft a hidden form or request that, if a logged-in WordPress user's browser happened to visit it, would silently submit an action to the WordPress site using that user's existing authenticated session — deleting content, changing settings, anything the form's target action could do. A nonce, generated specifically for that user's session and that specific action, defeats this because the malicious site has no way to know or predict the correct nonce value to include.
Why This Sometimes Causes Visible Errors
- Nonces expire after a limited time (commonly around 24 hours, though effectively shorter in practice for a form left open), so a form submitted long after the page loaded can fail verification, producing a "security check failed" style error — covered in more detail for the WooCommerce checkout context elsewhere.
- A cached page serving a stale, already-expired nonce is a common cause of this error appearing more often than expected, since the embedded nonce was generated at the time the page was originally rendered and cached, not when the visitor actually loaded it.
- Custom AJAX functionality built without proper nonce verification is a real, common security gap in custom development, worth checking for in any custom form or AJAX handler.
Working With Nonces Correctly
- Always include and verify a nonce in any custom form or AJAX handler that performs a meaningful action, using WordPress's built-in
wp_nonce_field()andcheck_admin_referer()/wp_verify_nonce()functions. - Exclude forms and AJAX-heavy pages from page caching, since a cached, stale nonce is a common cause of confusing verification failures.
- If seeing "security check failed" errors frequently, check caching configuration first, as covered elsewhere in more detail.
Need custom form/AJAX functionality built with proper security? See WordPress bug fix.