Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Difference between revisions of "WordPress Nonces"

(clarifying what WordPress "nonces" really are)
(Migrated to DevHub)
 
(17 intermediate revisions by 10 users not shown)
Line 1: Line 1:
  +
Migrated to https://developer.wordpress.org/apis/security/nonces/
  +
  +
<!--
 
{{Languages|
 
{{Languages|
 
{{en|WordPress Nonces}}
 
{{en|WordPress Nonces}}
 
{{fr|Les Nonces WordPress}}
 
{{fr|Les Nonces WordPress}}
{{ja|WordPress Nonces}}
+
{{ja|WordPress Nonce}}
 
}}
 
}}
   
A ''[[Glossary#Nonce|nonce]]'' is a "number used once" to help protect URLs and forms from certain types of misuse, malicious or otherwise. WordPress nonces aren't numbers, but are a hash made up of numbers and letters. Nor are they used only once, but have a limited "lifetime" after which they expire. During that time period the same nonce will be generated for a given user in a given context. The nonce for that action will remain the same for that user until that nonce life cycle has completed.
+
A ''[[Glossary#Nonce|nonce]]'' is a "number used once" to help protect URLs and forms from certain types of misuse, malicious or otherwise. WordPress nonces aren't numbers but are a hash made up of numbers and letters. Nor are they used only once, but have a limited "lifetime" after which they expire. During that time period, the same nonce will be generated for a given user in a given context. The nonce for that action will remain the same for that user until that nonce life cycle has completed.
   
WordPress's security tokens are called "nonces" despite the above noted differences from true nonces, because they serve much the same purpose as nonces do. They help protect against several types of attacks including CSRF, but do not protect against replay attacks because they aren't checked for one-time use.
+
WordPress's security tokens are called "nonces" (despite the above-noted differences from true nonces) because they serve much the same purpose as nonces do. They help protect against several types of attacks including CSRF, but do not protect against replay attacks because they aren't checked for one-time use. Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using [[Function Reference/current_user_can|<tt>current_user_can()</tt>]], and always assume nonces can be compromised.
   
  +
== Why use a nonce? ==
For an example of how an nonce is used, an admin screen might generate a URL like this that trashes post number 123. You can see that the URL contains a nonce at the end:
 
   
 
For an example of why a nonce is used, consider that an admin screen might generate a URL like this that trashes post number 123.
<nowiki>http://example.com/wp-admin/post.php?post=123&action=trash&_wpnonce=b192fc4204</nowiki>
 
   
  +
<nowiki>http://example.com/wp-admin/post.php?post=123&action=trash</nowiki>
If anyone attempts to modify the URL to trash post number 456, the nonce is not valid and the attempt fails:
 
   
  +
When you go to that URL, WordPress will validate your authentication cookie information and if you're allowed to delete that post will proceed to delete it. What an attacker can do with this is make your browser go to that URL without your knowledge. For example, the attacker could craft a disguised link on a 3rd party page like this:
<nowiki>http://example.com/wp-admin/post.php?post=456&action=trash&_wpnonce=b192fc4204</nowiki>
 
  +
  +
<nowiki><img src="http://example.com/wp-admin/post.php?post=123&action=trash" /></nowiki>
  +
  +
This would trigger your browser to make a request to WordPress, and the browser would automatically attach your authentication cookie and WordPress would consider this a valid request.
  +
  +
Adding a nonce would prevent this. For example, when using a nonce, the URLs that WordPress generate for the user look like this:
  +
 
<nowiki>http://example.com/wp-admin/post.php?post=123&action=trash&_wpnonce=b192fc4204</nowiki>
   
The invalid nonce causes WordPress to send a "403 Forbidden" response to the browser, with the error message: "Are you sure you want to do this?"
+
If anyone attempts to trash post number 123 without having the correct nonce generated by WordPress and given to the user, WordPress will send a "403 Forbidden" response to the browser, with the error message: "Are you sure you want to do this?"
   
 
== Creating a nonce ==
 
== Creating a nonce ==
Line 23: Line 34:
 
You can create a nonce and add it to the query string in a URL, you can add it in a hidden field in a form, or you can use it some other way.
 
You can create a nonce and add it to the query string in a URL, you can add it in a hidden field in a form, or you can use it some other way.
   
For nonces that are to be used in AJAX requests, it is common to add the nonce to a hidden field, from where JavaScript code can fetch it.
+
For nonces that are to be used in AJAX requests, it is common to add the nonce to a hidden field, from which JavaScript code can fetch it.
   
 
Note that the nonces are unique to the current user's session, so if a user logs in or out asynchronously any nonces on the page will no longer be valid.
 
Note that the nonces are unique to the current user's session, so if a user logs in or out asynchronously any nonces on the page will no longer be valid.
Line 96: Line 107:
 
wp_verify_nonce( $_REQUEST['my_nonce'], 'process-comment'.$comment_id );
 
wp_verify_nonce( $_REQUEST['my_nonce'], 'process-comment'.$comment_id );
   
If the result is false, do not continue processing the request. Instead take some appropriate action. The usual action is to call [[Function_Reference/wp_nonce_ays|wp_nonce_ays()]], which sends a "403 Forbidden" response to the browser with the error message: "Are you sure you want to do this?".
+
If the result is false, do not continue processing the request. Instead, take some appropriate action. The usual action is to call [[Function_Reference/wp_nonce_ays|wp_nonce_ays()]], which sends a "403 Forbidden" response to the browser with the error message: "Are you sure you want to do this?".
   
 
== Modifying the nonce system ==
 
== Modifying the nonce system ==
Line 108: Line 119:
 
add_filter( 'nonce_life', function () { return 4 * HOUR_IN_SECONDS; } );
 
add_filter( 'nonce_life', function () { return 4 * HOUR_IN_SECONDS; } );
   
Note that just as a WordPress nonce is not "a number used once", nonce lifetime isn't really nonce lifetime. WordPress uses a system with two ticks (half of the lifetime) and validates nonces from the current tick and the last tick. In default settings (24h lifetime) this means that the time information in the nonce is related to how many 12h periods of time have passed since Unix epoch. This means that a nonce made between midday and midnight will have a lifetime until midday the next day. The actual lifetime is thus variable between 12 and 24 hours. The example above will give you nonces that are valid for 2-4 hours.
+
Note that just as a WordPress nonce is not "a number used once", nonce lifetime isn't really nonce lifetime. WordPress uses a system with two ticks (half of the lifetime) and validates nonces from the current tick and the last tick. In default settings (24h lifetime) this means that the time information in the nonce is related to how many 12h periods of time have passed since the Unix epoch. This means that a nonce made between midday and midnight will have a lifetime until midday the next day. The actual lifetime is thus variable between 12 and 24 hours. The example above will give you nonces that are valid for 2-4 hours.
   
 
=== Performing additional verification ===
 
=== Performing additional verification ===
Line 115: Line 126:
   
 
function my_additional_check ( $action, $result ) { ... }
 
function my_additional_check ( $action, $result ) { ... }
add_action( 'check_admin_referrer', 'my_additional_check', 10, 2 );
+
add_action( 'check_admin_referer', 'my_additional_check', 10, 2 );
   
 
For check_ajax_referer() add a <code>check_ajax_referer</code> action in the same way.
 
For check_ajax_referer() add a <code>check_ajax_referer</code> action in the same way.
Line 124: Line 135:
   
 
function my_nonce_message ($translation) {
 
function my_nonce_message ($translation) {
if ($translation == 'Are you sure you want to do this?')
+
if ($translation === 'Are you sure you want to do this?') {
return 'No! No! No!';
+
return 'No! No! No!';
else
+
}
return $translation;
 
}
 
 
 
 
return $translation;
  +
}
 
 
add_filter('gettext', 'my_nonce_message');
 
add_filter('gettext', 'my_nonce_message');
   
 
== Additional information ==
 
== Additional information ==
   
This section contains additional information about the nonce system in Wordpress that might occasionally be useful.
+
This section contains additional information about the nonce system in WordPress that might occasionally be useful.
   
 
=== Nonce lifetime ===
 
=== Nonce lifetime ===
Line 143: Line 155:
   
 
Nonces are generated using a key and salt that are unique to your site if you have installed WordPress correctly. NONCE_KEY and NONCE_SALT are defined in your [[Editing_wp-config.php|wp-config.php]] file, and the file contains comments that provide more information.
 
Nonces are generated using a key and salt that are unique to your site if you have installed WordPress correctly. NONCE_KEY and NONCE_SALT are defined in your [[Editing_wp-config.php|wp-config.php]] file, and the file contains comments that provide more information.
  +
  +
Nonces should never be relied on for authentication or authorization, access control. Protect your functions using [[Function Reference/current_user_can|<tt>current_user_can()</tt>]], always assume Nonces can be compromised.
   
 
== Replacing the nonce system ==
 
== Replacing the nonce system ==
   
Some of the functions that make up the nonce system are [[Pluggable_Functions|pluggable]], so that you can replace them by supplying your own functions.
+
Some of the functions that make up the nonce system are [[Pluggable_Functions|pluggable]] so that you can replace them by supplying your own functions.
   
 
To change the way admin requests or AJAX requests are verified, you can replace check_admin_referrer() or check_ajax_referrer(), or both.
 
To change the way admin requests or AJAX requests are verified, you can replace check_admin_referrer() or check_ajax_referrer(), or both.
Line 162: Line 176:
 
== Resources ==
 
== Resources ==
 
* [http://markjaquith.wordpress.com/2006/06/02/wordpress-203-nonces/ WordPress 2.0.3: Nonces | Mark on WordPress]
 
* [http://markjaquith.wordpress.com/2006/06/02/wordpress-203-nonces/ WordPress 2.0.3: Nonces | Mark on WordPress]
* [http://www.prelovac.com/vladimir/improving-security-in-wordpress-plugins-using-nonces Improving security in Wordpress plugins using Nonces | Prelovac.com]
+
* [http://www.prelovac.com/vladimir/improving-security-in-wordpress-plugins-using-nonces Improving security in WordPress plugins using Nonces | Prelovac.com]
 
* [[Wikipedia:Cryptographic_nonce|Cryptographic nonce - Wikipedia, the free encyclopedia]]
 
* [[Wikipedia:Cryptographic_nonce|Cryptographic nonce - Wikipedia, the free encyclopedia]]
 
* [[Wikipedia:Cross-site_request_forgery|Cross-site request forgery - Wikipedia, the free encyclopedia]]
 
* [[Wikipedia:Cross-site_request_forgery|Cross-site request forgery - Wikipedia, the free encyclopedia]]
 
*[http://www.wp-entwickler.at/wordpress-sicherheit-bei-formulareingaben-und-ajax-aufrufen-verwendet-nonces/ Einführung zu Nonces und deren Verwendung] '''Artikel auf Deutsch'''
 
*[http://www.wp-entwickler.at/wordpress-sicherheit-bei-formulareingaben-und-ajax-aufrufen-verwendet-nonces/ Einführung zu Nonces und deren Verwendung] '''Artikel auf Deutsch'''
  +
*[https://codeseekah.com/2016/01/21/wordpress-nonces-vulnerabilities/ WordPress Nonce Vulnerabilities | codeseekah.com]
  +
*[https://www.bynicolas.com/code/wordpress-nonce/ How do WordPress nonces really work]
   
   
 
[[Category:Advanced_Topics]]
 
[[Category:Advanced_Topics]]
 
[[Category:Functions]]
 
[[Category:Functions]]
  +
-->

Latest revision as of 17:17, 6 December 2022

Migrated to https://developer.wordpress.org/apis/security/nonces/