WordPress Plugin Development In Bangla Part-9: WordPress Plugins Security with Nonce

wordpress nonce

wordpress nonce

WordPress এ Nonce কি?

WordPress Plugins Security

WordPress এ Nonce (number used once) হচ্ছে মূলতঃ WordPress এ randomly generated security hash সিস্টেম, tokens বা একটা unique identifiers , যা দিয়ে আমরা form ,url অথবা ajax request কোথায় থেকে আসছে , তা চেক করতে পারি। এবং এর মাধ্যমে WordPress site এ যেকোনো ক্ষতিকর attack থেকে সুরক্ষা দিতে পারি।

WordPress এ Nonce security প্রধানের জন্য ফাঙ্কশন গুলো দুইভাগে বিভক্ত :

1. Creating a Nonce

  • wp_nonce_url() – সাইটে যেকোনো URL তৈরির সময় তার সাথে একটা nonce যুক্ত করার কাজে ব্যবহৃত হয়। এবং URL এ অবস্থিত & গুলোকে & তে escapes করে।
  • wp_nonce_field() – সাইটের মধ্যে যেকোনো form এ একটা nonce hidden field যুক্ত করার কাজে ব্যবহৃত হয়।
  • wp_create_nonce() – custom nonce তৈরির কাজে ব্যবহৃত হয়। বিশেষ করে ajax request এর সময় এটি বেশি ব্যবহৃত হয়।এছাড়া আপনি চাইলে এটাকে form, url এমনকি session এর জন্য ও ব্যবহার করতে পারেন।

2. Verifying a Nonce

  • check_admin_referer() –শুধু মাত্র এক admin screen থেকে অন্য admin screen এর জন্য pass হওয়া nonce কে ভেরিফাই করার কাজে ব্যবহৃত হয়।
  • check_ajax_referer() – ajax এর জন্য nonce চেক করে। অর্থাৎ ajax request টি যদি আপন সাইট থেকে আসে, তাহলে সাইটে একসেস এর সুযোগ দিবে। অন্যথায় script execution সাথে সাথে terminate করে দিবে।
  • wp_verify_nonce() – Time limit দিয়ে nonce চেক করার জন্য এটি ব্যবহৃত হয়।

wp_nonce_url() Function Syntax

wp_nonce_url( 
    string $actionurl, 
    int|string $action = -1, 
    string $name = '_wpnonce' 
)

Parameters#

  • $actionurl (string) (Required) যেই URL এ nonce action টি যুক্ত করবেন , তা এখানে দিতে হবে।
  • $action (int|string) (Optional) Nonce এর action টির নাম এখানে দিতে পারেন। Default value: -1
  • $name (string) (Optional) Nonce এর একটা নাম দিতে পারেন। Default value: ‘_wpnonce’

উদাহরণঃ

// Sample URL, note the & in there
$url = 'http://localhost/?arg1=value1&arg2=value2';
 
// This will show http://localhost/?arg1=value1&arg2=value2&_wpnonce=abcdef
echo wp_nonce_url( $url, 'action' );
 
// This will return http://localhost/?arg1=value1&arg2=value2&_wpnonce=abcdef
echo add_query_arg( '_wpnonce', wp_create_nonce( 'action' ), $url );

wp_verify_nonce() function syntax

wp_verify_nonce(
    string $nonce,
    string|int $action = -1
);

Parameters #

  • $nonce (string) (Required) যেই Nonce value কে verification করবেন, তা এখানে হবে, এটা সাধারণত form, url অথবা ajax রিকোয়েস্ট থেকে এসে থাকে।
  • $action (string|int) (Optional) nonce টি যেই স্ট্রিং বা টোকেনের বিপরীতে তৈরি করেছিলেন , তা এখানে হবে। Default value: -1

URL Nonce Verification Plugin

এখন আমরা URL দিয়ে আসা একটা nonce কে ভেরিফিকেশন কিভাবে করা যায়, তা একটা প্লাগিনের মাধ্যমে দেখব। নিচের প্লাগিন টি দেখুন :

<?php
/*
Plugin Name: W3 URL Nonce Checking Plugin
Plugin URI: https://github.com/w3programmers/w3-url-nonce/
Description: W3 URL Nonce Checking Plugin
Author: Masud Alam
Version: 1.0.0
Author URI: http://w3programmers.com/
*/

add_action('admin_menu', 'add_my_plugin_admin_screen');
function add_my_plugin_admin_screen () {
    add_options_page(
        __('My Plugin Settings', 'my-plugin-textdomain'),
        __('My Plugin', 'my-plugin-textdomain'),
        'manage_options',
        'my_plugin_settings',
        'my_plugin_do_something'
    );
}
 
function my_plugin_do_something () {
    if (!isset($_GET['my_nonce']) || !wp_verify_nonce($_GET['my_nonce'], 'doing_something')) {
?>
<h2><?php esc_html_e('My Plugin Admin Screen', 'my-plugin-textdomain');?></h2>
<p>
    <a href="<?php print wp_nonce_url(admin_url('options-general.php?page=my_plugin_settings'), 'doing_something', 'my_nonce');?>"
        class="button button-primary"><?php esc_html_e('Do Something!', 'my-plugin-textdomain');?></a>
    <span class="description"><?php esc_html_e('This button does something interesting.', 'my-plugin-textdomain');?></span>
</p>
<?php
    } else {
        // User pressed "Do Something!" button, so
        // do something interesting.
        $nonce=$_GET['my_nonce'];
        echo "Hey! Your Nonce is: ".$nonce,"<br>";
        $nonce = wp_verify_nonce( $nonce, 'doing_something' );
switch ( $nonce ) {
    case 1:
        echo 'Nonce is less than 12 hours old';
        break;
    case 2:
        echo 'Nonce is between 12 and 24 hours old';
        break;
    default:
        exit( 'Nonce is invalid' );
}
    }
}

এখন যদি, আপনি প্লাগিনটি activate করেন, তাহলে নিচের মতো আপনার nonce রেজাল্ট দেখতে পাবেন।

before click url button

before click url button

এখন যদি, আপনি বাটনটি ক্লিক করেন , তাহলে নিচের মতো nonce value দেখতে পাবেন।

after click button

after click button

wp_nonce_field() function syntax

wp_nonce_field(
    int|string $action = -1, 
    string $name = '_wpnonce', 
    bool $referer = true, 
    bool $echo = true 
)

Parameters #

  • $action (int|string) (Optional) চাইলে এখানে একটা Action এর নাম দিতে পারেন। Default value: -1
  • $name (string) (Optional) এখানে Nonce এর নামটি দিতে পারেন। Default value: ‘_wpnonce’
  • $referer (bool) (Optional) referer field টি validation করবে কিনা তার জন্য এখানে একটা বুলিয়ান ভ্যালু দিতে পারেন। Default value: true
  • $echo (bool) (Optional) hidden form field টি display নাকি return করবে , তা এখানে বলতে পারেন। Default value: true

উদাহরণঃ

<form method="post">
   <!-- some inputs here ... -->
   <?php wp_nonce_field( 'name_of_my_action', 'name_of_nonce_field' ); ?>
</form>

Form Nonce Verification Plugin

এখন আমরা wp_nonce_field() function এবং form ব্যবহার করে একটা প্লাগিন তৈরি করে ফেলব। চলুন শুরু করা যাক।

<?php
/*
Plugin Name: W3 Form Nonce Checking Plugin
Plugin URI: https://github.com/w3programmers/w3-nonce-form/
Description: W3 Form Nonce Checking Plugin
Author: Masud Alam
Version: 1.0.0
Author URI: http://w3programmers.com/
*/

add_action('admin_menu', 'add_w3_nonce_form_admin_screen');
function add_w3_nonce_form_admin_screen () {
    add_options_page(
        __('W3 Nonce Form Plugin Settings', 'w3-nonce-form-plugin-textdomain'),
        __('W3 Nonce Form Plugin', 'w3-nonce-form-plugin-textdomain'),
        'manage_options',
        'w3_nonce_form_plugin_settings',
        'w3_nonce_form_plugin_do_something'
    );
}
 
function w3_nonce_form_plugin_do_something () {
    if (!isset($_REQUEST['w3_nonce_field']) || !wp_verify_nonce($_REQUEST['w3_nonce_field'], 'doing_something')) {
?>
<h2><?php esc_html_e('W3 Nonce Form Plugin Admin Screen', 'w3-nonce-form-plugin-textdomain');?></h2>
<form method="post" action="<?php echo admin_url('options-general.php?page=w3_nonce_form_plugin_settings');?>">
   <!-- some inputs here ... -->
   <?php wp_nonce_field( 'doing_something', 'w3_nonce_field' ); ?>
   <input class="button button-primary" type="submit" value="Check Nonce Value" name="submit">
</form>

<?php
    } else {
        // User pressed "Do Something!" button, so
        // do something interesting.
        $nonce=$_REQUEST['w3_nonce_field'];
        echo "Hey! Your Nonce is: ".$nonce,"<br>";
        $nonce = wp_verify_nonce( $nonce, 'doing_something' );
switch ( $nonce ) {
    case 1:
        echo 'Nonce is less than 12 hours old';
        break;
    case 2:
        echo 'Nonce is between 12 and 24 hours old';
        break;
    default:
        exit( 'Nonce is invalid' );
}
    }
}

এখন যদি আপনি form টি সাবমিট করেন , তাহলে নিচের মতো রেজাল্ট দেখতে পাবেন।

w3 nonce form output after submit

w3 nonce form output after submit

wp_create_nonce() Function Syntax

wp_create_nonce( 
string|int $action = -1 
)

Parameter #

  • $action (int|string) (Optional) চাইলে এখানে একটা Action এর নাম দিতে পারেন। Default value: -1

উদাহরণঃ

/*
 * Step A: Create an nonce for a link.
 * We pass it as a GET parameter.
 * The target page will perform some action based on the 'do_something' parameter.
 */
$nonce = wp_create_nonce( 'my-nonce' );
?>
<a href='myplugin.php?do_something=some_action&_wpnonce=<?php echo esc_attr( $nonce ); ?>'><?php esc_html_e( 'Do some action', 'textdomain' ); ?></a>
 
 
/*
 * Step B: This code would go in the target page.
 * We need to verify the nonce.
 */
$nonce = $_REQUEST['_wpnonce'];
if ( ! wp_verify_nonce( $nonce, 'my-nonce' ) ) {
    // This nonce is not valid.
    die( __( 'Security check', 'textdomain' ) ); 
} else {
    // The nonce was valid.
    // Do stuff here.
}

WordPress Plugins Security

তবে specific কিছু চেক করার জন্য ও আমরা চাইলে wp_create_nonce() function টি ব্যবহার করতে পারি। যেমন আপনি একটা ডিলিট রিকোয়েস্ট নিচের মতো করে nonce সহ পাঠাতে পারেন।

wp_create_nonce( 'delete_post-' . $post_id );

আর ডিলিট করার সময় , নিচের মতো করে ভেরিফাই করে নিতে পারবেন।

wp_verify_nonce( $nonce, "delete_post-{$_REQUEST['post_id']}" );

AJAX Request Nonce Verification Plugin

এখন আমরা wp_create_nonce() function এবং ajax ব্যবহার করে একটা প্লাগিন তৈরি করে ফেলব। চলুন শুরু করা যাক।

<?php
/*
Plugin Name: W3 Demo Ajax Plugin
Description: An Example of AJAX in WordPress Plugin
Plugin URI: https://github.com/w3programmers/w3-demo-ajax
Version: 1.0.0
Author: Masud Alam
Author URI: http://w3programmers.com
Text Domain: w3-demo-ajax
*/

add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue() {

    wp_register_script(
        'ajax-script', 
        plugins_url( '/js/script.js', __FILE__ ), 
        array('jquery') );    

	wp_enqueue_script('ajax-script');

    // in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.name
    $ajax_nonce = wp_create_nonce( "w3-security" );
    wp_localize_script( 
        'ajax-script', 
        'ajax_object',
        array( 
            'ajax_url' => admin_url( 'admin-ajax.php' ), 
            'nonce' =>  $ajax_nonce,
            'name' => "Masud Alam",
            'age'=>35,
        ));
    
}

add_action("wp_ajax_{$_REQUEST['action']}", 'receive_data' );

function receive_data() {
    $nonce = $_POST['nonce'];
   if (!wp_verify_nonce( $nonce, 'w3-security' ) ){
        die ( 'Busted!');
    } 
    $name= $_POST['name'];
    $age=  $_POST['age'];
    echo "Welcome! ".$name." You're ".$age." Years Old! Your Uniquue Security Code: $nonce";

	wp_die(); // this is required to terminate immediately and return a proper response
}

এবার আপনার plugin ফোল্ডারের মধ্যে , js/script.js ফাইলে নিচের কোডগুলো লিখুন।

jQuery(document).ready(function($) {
	var data = {
        'action': 'send_data',
        'name': ajax_object.name,      // We pass php values differently!
        'age' :ajax_object.age,
        'nonce':ajax_object.nonce,
	};
	// We can also pass the url value separately from ajaxurl for front end AJAX implementations
	jQuery.post(ajax_object.ajax_url, data, function(response) {
		alert(response);
	});
});

WordPress Plugins Security

এখন যদি আপনি প্লাগিনটি activate করেন, তাহলে নিচের মতো রেজাল্ট দেখতে পাবেন:

ajax with nonce

ajax with nonce

check_ajax_referer() Function Syntax

check_ajax_referer(
    int|string $action = -1, 
    false|string $query_arg = false, 
    bool $die = true 
)

Parameters #

  • $action (int|string) (Optional) চাইলে এখানে action nonce অর্থাৎ যেই string এর nonce তৈরী করেছেন , তা এখানে দিতে পারেন। Default value: -1
  • $query_arg (false|string) (Optional) $_REQUEST দিয়ে যেই নামে receive করবেন, চাইলে সেটি এখানে দিতে পারেন। যদি false থাকে তাহেল বাই ডিফল্ট এখানে ভ্যালু হিসেবে নিবে ‘_ajax_nonce’, এবং ‘_wpnonce’ . Default value: false
  • $die (bool) (Optional) AJAX nonce না মিললে সাথে সাথে script execution অফ হবে কিনা , তা এখানে চাইলে দিতে পারেন Default value: true

উদাহরণঃ

এখন চাইলে আপনি আমাদের উপরের “W3 Demo Ajax Plugin” এ wp_verify_nonce() ফাঙ্কশনটি ব্যবহারের পরিবর্তে check_ajax_referer() ফাঙ্কশনটি ব্যবহার করতে পারেন। নিচে লক্ষ্য করুন :

<?php
/*
Plugin Name: W3 Demo Ajax Plugin
Description: An Example of AJAX in WordPress Plugin
Plugin URI: https://github.com/w3programmers/w3-demo-ajax
Version: 1.0.0
Author: Masud Alam
Author URI: http://w3programmers.com
Text Domain: w3-demo-ajax
*/

add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue() {

    wp_register_script(
        'ajax-script', 
        plugins_url( '/js/script.js', __FILE__ ), 
        array('jquery') );    

	wp_enqueue_script('ajax-script');

    // in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.name
    $ajax_nonce = wp_create_nonce( "w3-security" );
    wp_localize_script( 
        'ajax-script', 
        'ajax_object',
        array( 
            'ajax_url' => admin_url( 'admin-ajax.php' ), 
            'nonce' =>  $ajax_nonce,
            'name' => "Masud Alam",
            'age'=>35,
        ));
    
}

add_action("wp_ajax_{$_REQUEST['action']}", 'receive_data' );

function receive_data() {
    $nonce = $_POST['nonce'];
  /*  if (!wp_verify_nonce( $nonce, 'w3-security' ) ){
        die ( 'Busted!');
    }  */
    check_ajax_referer( 'w3-security', 'nonce', true );
    $name= $_POST['name'];
    $age=  $_POST['age'];
    echo "Welcome! ".$name." You're ".$age." Years Old! Your Uniquue Security Code: $nonce";

	wp_die(); // this is required to terminate immediately and return a proper response
}

check_admin_referer() Function Syntax

check_admin_referer(
    int|string $action = -1, 
    string $query_arg = '_wpnonce' 
);

Parameters #

  • $action (int|string) (Optional) nonce action টির নাম এখানে হবে। Default value: -1
  • $query_arg (string) (Optional) nonce field এর নামটি এখানে হবে। অর্থাৎ যেই key দিয়ে আপনি $_REQUEST দিয়ে nonce value রিসিভ করবেন। Default value: ‘_wpnonce’

উদাহরণঃ

এখন আমরা আমাদের ইতিমধ্যে ডেভেলপ করা “W3 Form Nonce Checking Plugin” এ wp_verify_nonce() ফাঙ্কশনের পরিবর্তে check_admin_referer() function দিয়ে নতুন করে সাজাবো। নিম্নে লক্ষ্য করুন :

<?php
/*
Plugin Name: W3 Form Nonce Checking Plugin
Plugin URI: https://github.com/w3programmers/w3-nonce-form/
Description: W3 Form Nonce Checking Plugin
Author: Masud Alam
Version: 1.0.0
Author URI: http://w3programmers.com/
*/

add_action('admin_menu', 'add_w3_nonce_form_admin_screen');
function add_w3_nonce_form_admin_screen () {
    add_options_page(
        __('W3 Nonce Form Plugin Settings', 'w3-nonce-form-plugin-textdomain'),
        __('W3 Nonce Form Plugin', 'w3-nonce-form-plugin-textdomain'),
        'manage_options',
        'w3_nonce_form_plugin_settings',
        'w3_nonce_form_plugin_do_something'
    );
}
 
function w3_nonce_form_plugin_do_something () {
?>
<h2><?php esc_html_e('W3 Nonce Form Plugin Admin Screen', 'w3-nonce-form-plugin-textdomain');?></h2>

<?php
  if ( ! empty( $_POST ) && check_admin_referer( 'doing_something', 'w3_nonce_field' ) ){
        // User pressed "Do Something!" button, so
        // do something interesting.
        $nonce=$_REQUEST['w3_nonce_field'];
        echo "Hey! Your Nonce is: ".$nonce,"<br>";
    }
    ?>
    <form method="post" action="<?php echo admin_url('options-general.php?page=w3_nonce_form_plugin_settings');?>">
    <!-- some inputs here ... -->
    <?php wp_nonce_field( 'doing_something', 'w3_nonce_field' ); ?>
    <input class="button button-primary" type="submit" value="Check Nonce Value" name="submit">
 </form>
 <?php
}

WordPress Plugins Security

এখন যদি আপনি Plugin টি Activate করেন , তাহলে নিচের মতো রেজাল্ট দেখতে পাবেন।

আর যদি আপনি form টি submit করেন , তাহলে নিচের মতো রেজাল্ট দেখতে পাবেন।

WordPress Nonce Verification

WordPress Nonce Verification

আবার যদি nonce ঠিক না থাকে , তাহলে check_admin_referer() function ইমিডিয়েট নিচের মতো রেজাল্ট দিবে।

lilligal nonce example

lilligal nonce example

Masud Alam
আমি মাসুদ আলম, বাংলাদেশের ৩৬ তম Zend Certified Engineer । ২০০৯ সালে কম্পিউটার সাইন্স থেকে বেচেলর ডিগ্রী অর্জন করি। দীর্ঘ ৮ বছর আমি Winux Soft, SSL Wireless, IBCS-PRIMAX, Max Group, Canadian International Development Agency (CIDA), Care Bangladesh, World Vision, Hellen Keller সহ বিভিন্ন দেশি বিদেশী কোম্পানিতে ওয়েব ডেভেলপমেন্ট এবং সফটওয়্যার ডেভেলপমেন্ট এর উপর বিভিন্ন লিডিং পজিশন এ চাকরি এবং প্রজেক্ট লিড করি। বিশেষ ভাবে বাংলাদেশের ১০০ জন জেন্ড সার্টিফাইড ইঞ্জিনিয়ার এর মধ্যে ৫২ জন ই আমার হাতে জেন্ড সার্টিফাইড হয়েছে। বর্তমানে TechBeeo Software Company তে সিইও হিসাবে আছি । পাশাপাশি w3programmers ট্রেনিং ইনস্টিটিউট এ PHP এর উপর Professional এবং Advance Zend Certified PHP -7 Engineering কোর্স করাই। আর w3programmers.com সাইট টি আমার।

Leave a Reply