阅读数 wordpress_什么是WordPress随机数?

阅读数 wordpress

Keeping your WordPress theme or plugin code secure is important to prevent possible attacks from malicious users.

确保WordPress主题或插件代码的安全对防止恶意用户可能的攻击非常重要。

We’ve previously covered how to sanitize, escape and validate form data in WordPress, as well as improving your WordPress theme quality with the VIP Scanner.

我们之前已经介绍了如何在WordPress中清理,转义和验证表单数据 ,以及如何使用VIP Scanner改善WordPress主题质量

Today we’ll look at how nonces (number used once) can also help keep your WordPress themes and plugins secure.

今天,我们将研究随机数(一次使用的数字)还可以如何帮助确保WordPress主题和插件的安全。

什么是WordPress随机数? (What Are WordPress Nonces?)

WordPress nonces are defined as:

WordPress的现时定义为:

… a “number used once” to help protect URLs and forms from certain types of misuse, malicious or otherwise. https://codex.wordpress.org/WordPress_Nonces

…“一次使用的数字”可帮助保护URL和表单免受某些类型的滥用,恶意或其他形式的滥用。 https://codex.wordpress.org/WordPress_Nonces

Whilst in WordPress a nonce isn’t technically a number (it’s a hash made up of letters and numbers), it does help prevent actions from being run by malicious users.

虽然在WordPress中,随机数从技术上讲不是数字(它是由字母和数字组成的哈希),但确实有助于防止恶意用户执行操作。

WordPress nonces work in two parts:

WordPress随机数分为两个部分:

  • Creating a nonce (hash), submitting it via a form or action, and

    创建随机数(哈希),通过表单或操作将其提交,以及
  • Verifying a nonce, before accepting form data or running an action.

    在接受表单数据或执行操作之前,请先验证随机数。

For example, when you go to delete a post in the WordPress Administration Screen, you’ll notice the URL contains a _wpnonce parameter: http://127.0.0.1/tuts/wp-admin/post.php?post=542&action=trash&_wpnonce=a03ac85772

例如,当您在WordPress管理屏幕中删除帖子时,您会注意到URL包含_wpnonce参数: http://127.0.0.1/tuts/wp-admin/post.php?post=542&action=trash&_wpnonce=a03ac85772 : http://127.0.0.1/tuts/wp-admin/post.php?post=542&action=trash&_wpnonce=a03ac85772 _wpnonce http://127.0.0.1/tuts/wp-admin/post.php?post=542&action=trash&_wpnonce=a03ac85772

The routine, which deletes a post, will check that post 542 has a nonce value of a03ac85772 before deleting the post. If the nonce does not exist, or does not match the expected value, the post will not be deleted.

删除帖子的例程将在删除帖子之前检查帖子542的现时值为a03ac85772。 如果现时不存在或与预期值不匹配,则不会删除该帖子。

This prevents a malicious user potentially deleting lots of posts. For example, the following wouldn’t work, as the nonce belongs to post ID 542:http://127.0.0.1/tuts/wp-admin/post.php?post=642&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=742&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=842&action=trash&_wpnonce=a03ac85772

这样可以防止恶意用户潜在地删除大量帖子。 例如,以下内容将不起作用,因为http://127.0.0.1/tuts/wp-admin/post.php?post=642&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=742&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=842&action=trash&_wpnonce=a03ac85772数属于帖子ID 542: http://127.0.0.1/tuts/wp-admin/post.php?post=642&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=742&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=842&action=trash&_wpnonce=a03ac85772 post http://127.0.0.1/tuts/wp-admin/post.php?post=642&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=742&action=trash&_wpnonce=a03ac85772 http://127.0.0.1/tuts/wp-admin/post.php?post=842&action=trash&_wpnonce=a03ac85772

Are you sure you want to do this

Let’s now look at how we can implement WordPress nonces in a plugin

现在让我们看一下如何在插件中实现WordPress nonce

设置我们的WordPress插件 (Setting up Our WordPress Plugin)

Let’s start with a basic plugin that has its own settings screen. The settings screen has a field, which can be submitted and saved in the WordPress options table.

让我们从一个具有自己的设置屏幕的基本插件开始。 设置屏幕上有一个字段,可以提交并保存在WordPress选项表中。

Enter the below code in a new file at wp-content/plugins/implementing-wordpress-nonces/implementing-wordpress-nonces.php:

wp-content/plugins/implementing-wordpress-nonces/implementing-wordpress-nonces.php的新文件中输入以下代码:

plugin = new stdClass;
        $this->plugin->name         = 'implementing-wordpress-nonces'; // Plugin Folder
        $this->plugin->displayName  = 'Nonces'; // Plugin Name

		add_action( 'admin_menu', array( &$this, 'admin_menu' ) );

	}

	/**
    * Register the plugin settings panel
    *
    * @since 1.0.0
    */
    function admin_menu() {

        add_menu_page( $this->plugin->displayName, $this->plugin->displayName, 'manage_options', $this->plugin->name, array( &$this, 'admin_screen' ), 'dashicons-admin-network' );

    }

    /**
    * Output the Administration Screens
    * Save POSTed data from the Administration Panel into a WordPress option
    *
    * @since 1.0.0
    */
    function admin_screen() {

        // Save Settings
        if ( isset( $_REQUEST['submit'] ) ) {
        	update_option( 'implementing_wordpress_nonces', sanitize_text_field( $_REQUEST[ 'implementing_wordpress_nonces' ] ) );
        	$message = __( 'Settings saved', $this->plugin->name );
        }

        // Output form
        ?>
   
   

plugin->displayName; ?>

Activate the plugin via the WordPress Administration > Plugins screen, and you’ll see a new Nonces menu item displayed:
Nonces

Click this, and you’ll be taken to the settings screen with a single field:

Enter any value, click Save, and if everything worked, you’ll see confirmation, along with the value you’ve just entered:

Demonstrating the Security Flaw

Enter the following URL into your web browser’s address bar (replacing the domain with where you have WordPress installed): http://127.0.0.1/tuts/wp-admin/admin.php?page=implementing-wordpress-nonces&implementing_wordpress_nonces=abc

Nonces

Notice what happened? The value was saved as abc, simply by directly accessing a URL and being logged into WordPress:

Whilst we could use $_POST instead of $_REQUEST in our code (we’ve used $_REQUEST to make it easier to demonstrate the security issue), this wouldn’t help – a malicious user could still, either by themselves or by tricking you into clicking a link – get you to send a POST request to this screen, resulting in the option value being changed.

This is known as a Cross-Site Request Forgery (or CSRF). It’s where a malicious web site, email, application, etc. causes the user’s web browser to perform an unwanted action.

We’ll now create and verify a WordPress nonce, to prevent this attack from being possible.

Securing Our Plugin with a Nonce

As mentioned earlier, there are two steps to the process: first, we need to create a nonce that will be submitted with our form. Second, we need to verify that nonce when the form is submitted.

To create a nonce field in our form, we can use wp_nonce_field():

Retrieves or displays the nonce hidden form field… used to validate that the contents of the form request came from the current site and not somewhere else…

Add the following code just above our input button:

[php]wp_nonce_field( 'implementing_wordpress_nonces_save', 'implementing_wordpress_nonces_nonce' );

wp_nonce_field accepts four arguments – the first two are most important:

wp_nonce_field接受四个参数-前两个参数最重要:

  • $action: This determines the specific action we’re running, and should be unique. It’s good practice to prefix your action with the plugin name, as potentially several actions may run. In this case, we’re saving something, so we’ve used implementing_wordpress_nonces_save

    $action :这确定我们正在运行的特定操作,并且应该是唯一的。 最好在操作之前加上插件名称,因为可能会运行多个操作。 在这种情况下,我们要保存一些内容,因此我们使用了implementing_wordpress_nonces_save

  • $name: This determines the name of the hidden field created by this function. As above, we’ve prefixed this with our plugin name, therefore calling it implementing_wordpress_nonces_nonce

    $name :它确定此函数创建的隐藏字段的名称。 如上所述,我们在此名称之前加上了插件名称,因此将其称为implementing_wordpress_nonces_nonce

If we reload the settings screen, change our value and click Save, you’ll notice the value still changes. We now need to implement a check for the nonce field that was submitted, using wp_verify_nonce( $name, $action ):

如果我们重新加载设置屏幕,请更改我们的值,然后单击“保存”,您会注意到该值仍在更改。 现在,我们需要使用wp_verify_nonce( $name, $action )提交的现时字段执行检查:

Verify that a nonce is correct and unexpired with the respect to a specified action. The function is used to verify the nonce sent in the current request usually accessed by the $_REQUEST PHP variable.

验证随机数正确无误且未过期。 该函数用于验证通常由$ _REQUEST PHP变量访问的当前请求中发送的随机数。

Replace the Save Settings section of our plugin’s admin_screen() function with code the below:

用以下代码替换我们插件的admin_screen()函数的Save Settings部分:

// Save Settings
if ( isset( $_REQUEST['implementing_wordpress_nonces'] ) ) {
	if ( isset( $_REQUEST[ 'implementing_wordpress_nonces_nonce' ] ) && wp_verify_nonce( $_REQUEST[ 'implementing_wordpress_nonces_nonce' ], 'implementing_wordpress_nonces_save' ) ) {
    	update_option( 'implementing_wordpress_nonces', sanitize_text_field( $_REQUEST[ 'implementing_wordpress_nonces' ] ) );
    	$message = __( 'Settings saved', $this->plugin->name );
    } else {
    	// Nonce could not be verified - bail
    	wp_die( __( 'Invalid nonce specified', $this->plugin->name ), __( 'Error', $this->plugin->name ), array(
    		'response' 	=> 403,
    		'back_link' => 'admin.php?page=' . $this->plugin->name,
    	) );
	}
}

This code performs a few actions:

此代码执行一些操作:

  • First, it checks that we’ve submitted something.

    首先,它检查我们是否已提交某些内容。
  • Then, it checks that our nonce field exists, and if so attempts to verify the nonce’s value against the action we’re expecting.

    然后,它检查我们的nonce字段是否存在,如果存在,则尝试根据我们期望的操作来验证nonce的值。
  • If the checks pass, the option is updated.

    如果检查通过,则该选项将更新。
  • If the checks fail, we throw a 403 error with the message “Invalid nonce specified”.

    如果检查失败,我们将引发403错误,并显示消息“指定了无效的随机数”。

To ensure our nonces are being created and validated, let’s try to access our ‘malicious’ direct URL again: http://127.0.0.1/tuts/wp-admin/admin.php?page=implementing-wordpress-nonces&implementing_wordpress_nonces=abc.

为确保创建并验证我们的现时值,让我们尝试再次访问“恶意”直接URL: http://127.0.0.1/tuts/wp-admin/admin.php?page=implementing-wordpress-nonces&implementing_wordpress_nonces=abc : http://127.0.0.1/tuts/wp-admin/admin.php?page=implementing-wordpress-nonces&implementing_wordpress_nonces=abc ?page=implementing-wordpress-nonces&implementing_wordpress_nonces= http://127.0.0.1/tuts/wp-admin/admin.php?page=implementing-wordpress-nonces&implementing_wordpress_nonces=abc

Nonces

If our nonces are implemented and being verified, you’ll see the Invalid nonce specified notice:

如果我们的现时实现并得到验证,您将看到指定无效现时通知:

在AJAX请求中使用随机数 (Using Nonces in AJAX Requests)

Say we want to save changes via an AJAX call, rather than reload the entire screen. We can do this with a few code tweaks.

假设我们要通过AJAX调用保存更改,而不是重新加载整个屏幕。 我们可以通过一些代码调整来做到这一点。

First, let’s load some JavaScript into our plugin, and register an AJAX handler, by adding the following to our __construct():

首先,通过将以下内容添加到我们的__construct() ,将一些JavaScript加载到我们的插件中,并注册一个AJAX处理程序:

add_action( 'admin_enqueue_scripts', array( &$this, 'admin_scripts_css' ) );
add_action( 'wp_ajax_implementing_wp_nonces', array( &$this, 'admin_ajax_save' )  );

In our class, add the corresponding admin_scripts_css function:

在我们的课程中,添加相应的admin_scripts_css函数:

/**
* Register and enqueue any JS and CSS for the WordPress Administration
*
* @since 1.0.0
*/
function admin_scripts_css() {

	// JS
	wp_enqueue_script( $this->plugin->name, plugin_dir_url( __FILE__ ) . 'admin.js', array( 'jquery' ), '1.0', true );

}

For our AJAX call, add the corresponding admin_ajax_save function:

对于我们的AJAX调用,添加相应的admin_ajax_save函数:

/**
 * Saves POSTed settings data
 *
 * @since 1.0.0
 */
function admin_ajax_save() {

	// Save option and return 1
	update_option( 'implementing_wordpress_nonces', sanitize_text_field( $_REQUEST[ 'implementing_wordpress_nonces' ] ) );
	echo 1;
	die();

}

Finally, we need to create a new file in our plugin folder for our JavaScript routine, which will POST the data via AJAX when the form is submitted. Let’s do this by creating a new file called admin.js, inserting the following:

最后,我们需要在我们JavaScript例程的plugin文件夹中创建一个新文件,该文件将在提交表单时通过AJAX发布数据。 通过创建一个名为admin.js的新文件来完成此admin.js ,插入以下内容:

jQuery( document ).ready( function( $ ) {

	$( 'form#implementing-wordpress-nonces' ).submit( function( e ) {

		// Prevent form submission
		e.preventDefault();

		// Submit form via AJAX
		$.post(
	        ajaxurl, // Set by WordPress
	        {
	        	'action': 'implementing_wp_nonces',
	        	'implementing_wordpress_nonces': $( 'input#implementing_wordpress_nonces' ).val()
	        },
	        function(response) {
	            if ( response ) {
	            	alert( 'Settings Saved' );
	            }
	        }
	    );
    });

} );
Nonces

Reload our settings screen, and if everything worked, when you submit the form, you’ll get an on screen confirmation to say that the settings saved.

重新加载我们的设置屏幕,如果一切正常,则在提交表单时,您会在屏幕上看到一条确认信息,说设置已保存。

Nonces

We can reload the settings screen again to make sure the value did update successfully:

我们可以再次重新加载设置屏幕,以确保该值确实成功更新:

Again, we now need to implement both the creation and validation of a WordPress nonce, to ensure that CSRF attacks can’t happen via an AJAX request.

再次,我们现在需要实现WordPress随机数的创建和验证,以确保CSRF攻击不会通过AJAX请求发生。

For creating nonces for AJAX requests, we can use the WordPress wp_create_nonce function:

为了为AJAX请求创建随机数,我们可以使用WordPress wp_create_nonce函数:

Generates and returns a nonce. The nonce is generated based on the current time, the $action argument, and the current user ID.

生成并返回一个随机数。 随机数是根据当前时间,$ action参数和当前用户ID生成的。

It accepts a single $action argument, so we’d use:

它接受单个$action参数,因此我们将使用:

$nonce = wp_create_nonce( 'implementing_wordpress_nonces_ajax_save' );

To get this nonce hash into JavaScript’s scope, we can use wp_localize_script() to send a JS object. Let’s add the following code below the wp_enqueue_script call in our plugin:

为了使此随机数哈希值进入JavaScript的范围,我们可以使用wp_localize_script()发送JS对象。 让我们在插件的wp_enqueue_script调用下面添加以下代码:

wp_localize_script( $this->plugin->name, 'implementing_wordpress_nonces', array(
	'nonce' => wp_create_nonce( 'implementing_wordpress_nonces_ajax_save' ),
) );

We also need to update our JavaScript file to send this nonce value with the AJAX POST request:

我们还需要更新JavaScript文件,以通过AJAX POST请求发送此现时值:

jQuery( document ).ready( function( $ ) {

	$( 'form#implementing-wordpress-nonces' ).submit( function( e ) {

		// Prevent form submission
		e.preventDefault();

		// Submit form via AJAX
		$.post(
	        ajaxurl, // Set by WordPress
	        {
	        	'action': 'implementing_wp_nonces',
	        	'nonce':  implementing_wordpress_nonces.nonce,
	        	'implementing_wordpress_nonces': $( 'input#implementing_wordpress_nonces' ).val()
	        },
	        function(response) {
	        	if ( response == 1 ) {
	            	alert( 'Settings Saved' );
	            } else {
	            	alert( 'Invalid nonce specified' );
	            }
	        }
	    );
    });

} );

The JavaScript file now sends a $_POST variable called nonce with the value of wp_create_nonce.

现在,JavaScript文件将发送一个$_POST变量,称为nonce ,其值为wp_create_nonce

Finally, we need to verify the nonce when it’s sent in the AJAX request. Update our admin_ajax_save function:

最后,我们需要在AJAX请求中发送随机数时对其进行验证。 更新我们的admin_ajax_save函数:

/**
 * Saves POSTed settings data
 *
 * @since 1.0.0
 */
function admin_ajax_save() {

	// Run a security check first.
	check_ajax_referer( 'implementing_wordpress_nonces_ajax_save', 'nonce' );

	// Save option and return 1
	update_option( 'implementing_wordpress_nonces', sanitize_text_field( $_REQUEST[ 'implementing_wordpress_nonces' ] ) );
	echo 1;
	die();

}

This uses check_ajax_referer, which checks if the given $action (implementing_wordpress_nonces_ajax_save) exists for the given POST field $name (nonce).

它使用check_ajax_referer ,它检查给定的POST字段$name (一次)是否存在给定的$action (implementing_wordpress_nonces_ajax_save)。

If it fails, -1 will be returned, triggering our JavaScript file to show an alert:

如果失败,将返回-1,触发我们JavaScript文件以显示警报:

Nonces

If it succeeds, 1 will be returned, triggering our JavaScript file to show a success message:

如果成功,将返回1,触发我们JavaScript文件以显示成功消息:

Nonces

结论 (Conclusion)

We’ve learnt what a WordPress nonce is, and how WordPress uses nonces to prevent malicious CSRF attacks. By building a basic WordPress plugin, we’ve shown how a plugin – and WordPress – can potentially be exploited if nonces are not created and verified.

我们已经了解了WordPress随机数是什么,以及WordPress如何使用随机数来防止恶意CSRF攻击。 通过构建一个基本的WordPress插件,我们展示了如果不创建和验证随机数,则可以潜在地利用插件和WordPress。

Using wp_nonce_field() and wp_verify_nonce, we’ve shown how to validate nonces to prevent CSRF attacks. Finally, we implemented AJAX saving of POST data, and used wp_create_nonce and check_ajax_referer to ensure our AJAX requests are also as secure as possible.

使用wp_nonce_field()wp_verify_nonce ,我们展示了如何验证随机数以防止CSRF攻击。 最后,我们实现了POST数据的AJAX保存,并使用wp_create_noncecheck_ajax_referer来确保我们的AJAX请求也尽可能安全。

For the full source code, check out the GitHub repository or download the code directly.

有关完整的源代码, 请查看GitHub存储库直接下载代码

翻译自: https://www.sitepoint.com/what-are-wordpress-nonces/

阅读数 wordpress

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值