Where to use nonce

Well actually, you just need to learn and understand what nonce is and is for, and then you would know when/where/whether you should use it.

  • Excerpt from https://codex.wordpress.org/WordPress_Nonces:

    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 current_user_can(), and always assume nonces can be compromised.

  • Excerpts from https://developer.wordpress.org/plugins/security/nonces/:

    If your plugin allows users to submit data; be it on the Admin or the Public side; you have to make sure that the user is who they say they are and that they have the necessary capability to perform the action. Doing both in tandem means that data is only changing when the user expects it to be changing.

    Nonces can be used to check that the current user actually intends to perform the action.

So basically, using nonce is recommended, but we don’t need to add it to every form or link. You just need to decide based on what your form or link is for.

But if I were you, I might add an nonce to the meta box callbacks in question, as an added security measure. 🙂

Here’s an example of the code I would use:

And this is a simple example where I used a dummy field.

  1. In the __construct() method, add this:

    add_action( 'save_post_news', [ $this, 'save_post_settings' ] );
    

    So I used the save_post_<post type> hook to save the input as a post meta after the post is saved.

  2. And this is the save_post_settings() method:

    public function save_post_settings( $post_id ) {
        // Basic checks: Check if the post is not an auto-save or revision, and that its
        // post type is `news`.
        if ( wp_is_post_revision( $post_id ) || 'news' !== get_post_type( $post_id ) ) {
            return;
        }
    
        // Check that the nonce field was submitted and verify the nonce.
        if ( ! check_admin_referer( basename( __FILE__ ), 'news_nonce' ) ) {
            return;
        }
    
        // Check that the dummy field was submitted, and then sanitize the value and save
        // it as a post meta.
        if ( isset( $_POST['foo_input'] ) ) {
            $value = sanitize_text_field( $_POST['foo_input'] );
            update_post_meta( $post_id, 'foo_input', $value );
        }
    }
    

    Things to note: I used check_admin_referer() to verify the nonce coming from an admin page, sanitize_text_field() to secure/clean the input, and update_post_meta() to store the value in a post meta named foo_input.

  3. In the post_settings_html() method, add this, e.g. after calling the wp_nonce_field():

    // Add the dummy field.
    $foo_input = get_post_meta( $post->ID, 'foo_input', true );
    ?>
        <label for="foo_input">Enter something good: (HTML will be stripped)</label>
        <input type="text" name="foo_input" id="foo_input" class="widefat"
            value="<?php echo esc_attr( $foo_input ); ?>" />
    <?php
    

    So I used get_post_meta() to get the saved meta value and escape it using esc_attr() when displaying to the user.