0

I am learning WordPress Plugin Development. My Code is like below.

class Admin
{
    
    public function __construct()
    {        
        add_action( 'admin_menu', [$this,'news_meta_boxes'] );
    }

    public function news_meta_boxes()
    {
        add_meta_box('news_settings', 'News Settings', [ $this, 'post_settings_html' ], 'news', 'normal', 'default');
        add_meta_box('display_settings', 'Display Settings', [ $this, 'display_settings_html' ], 'news', 'normal', 'default');
        add_meta_box('style_settings', 'Color Settings', [ $this, 'style_settings_html' ], 'news', 'normal', 'default');
    }
    

    public function post_settings_html($post)
    {
        wp_nonce_field(basename(__FILE__), 'news_nonce');
    }


    public function display_settings_html($post)
    {
        
        wp_nonce_field(basename(__FILE__), 'news_nonce');
    }


    public function style_settings_html($post)
    {
        wp_nonce_field(basename(__FILE__), 'news_nonce');
    }
}

Should I use wp_nonce_field in every Metabox call back function ?

1
  • 1
    I saw your other question and then realized that I seemed to have misunderstood your actual question/concerns, hence I deleted my original answer and posted another one. If that still didn't answer your question, please clarify it.
    – Sally CJ
    Jul 16, 2022 at 16:42

1 Answer 1

3

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.