WordPress Nonces Can Not Be Used for Authentication
Last week we looked at a situation where very popular security plugins are using a security function in a way that the documentation explicitly states it shouldn’t be used. That turns out to not be a one-off problem. WordPress’ documentation for usage of nonces states clearly that they should not be used for authentication:
Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using current_user_can(), and always assume nonces can be compromised.
It is good advice, since there have been serious vulnerabilities in WordPress plugins that could have been avoided if that advice had been followed.
Usually, it isn’t possible to say if a developer is misusing a nonce for authentication or if they simply forgot to include authentication. That isn’t the case with code in a plugin with 20,000+ installs that we were looking at because of a possible security issue. The plugin has a comment that reads “Add nonce for security and authentication.” before a nonce check:
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | public function save_options() { // Add nonce for security and authentication. $nonce_name = isset( $_POST['tf_option_nonce'] ) ? $_POST['tf_option_nonce'] : ''; $nonce_action = 'tf_option_nonce_action'; // Check if a nonce is set. if ( ! isset( $nonce_name ) ) { return; } // Check if a nonce is valid. if ( ! wp_verify_nonce( $nonce_name, $nonce_action ) ) { return; } $tf_option_value = array(); |
Notably, there isn’t usage of current_user_can() before or after that.
This is our friendly reminder of the importance of proper usage of nonces. If you know a developer who needs a reminder of this, please point them to this post or to the relevant WordPress documentation.