Nonce 在 WordPress 中随处可见,不信按下F12在请求中可以发现很多。简单来说这个东西就是一个口令,用来分辨是不是合法的请求。看到水煮鱼大佬写得比较详细,拿来分享一下。
使用 Nonce 防止 WordPress 网站受到 CSRF 攻击
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
一个典型的CSRF攻击有着如下的流程:
- 受害者登录a.com,并保留了登录凭证(Cookie)。
- 攻击者引诱受害者访问了b.com。
- b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie。
- a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
- a.com以受害者的名义执行了act=xx。
- 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作。
WordPress Nonce 基本流程
使用 Nonce ( number used once ) 是防止 WordPress 受到 CSRF (cross-site request forgery) 攻击最好的方法,WordPress Nonce 通过提供一个随机数,来实现在数据请求(比如,在后台保存插件选项,AJAX 请求,执行其他操作等等)的时候防止未授权的请求。
WordPress Nonce 的主要工作流程:
- 首先使用一个唯一的标示符生成 nonce
- 将生成的 nonce 和链接或者表单中的其他数据一起传递给脚本
- 在做其他事情之前验证 nonce
首先可以使用 wp_create_nonce()
函数创建 nonce:
$nonce= wp_create_nonce('wpjam');
然后将生成 $nonce 的值作为参数传递给请求中,如:
<a href="admin.php?page=wpjam&_wpnonce=<?php echo $nonce ?>">
最后在执行其他动作的时候,使用 wp_verify_nonce()
函数验证下 nonce。
$nonce = $_REQUEST['_wpnonce']; if (!wp_verify_nonce($nonce, 'wpjam') ) { wp_die("非法操作"); }
所以整个过程还是非常简单的。
WordPress Nonce 函数
WordPress 还提供一些函数简化 nonce 在特殊场景下的使用。
比如在表单中,可以使用函数 wp_nonce_field()
输出一个值为 nonce 的隐藏输入框,可以在表单中任意位置插入:
<form action=... > <?php wp_nonce_field('wpjam'); ?> ... </form>
如果想在链接中加入 nonce,可以使用 wp_nonce_url()
函数:
<a href="<?php wp_nonce_url($url, 'wpjam'); ?>">
如果在 WordPress 后台页面,可以使用 check_admin_referer()
函数验证 nonce,它会自动从链接的查询参数中获取 nonce 并验证它:
check_admin_referer( 'wpjam');
在 AJAX 中使用 Nonce
在 AJAX 脚本中 nonce 也是非常容易的,首先使用 wp_create_nonce()
函数创建 nonce:
$nonce = wp_create_nonce('wpjam');
然后将 $nonce 作为 _ajax_nonce
参数的值传递给 AJAX 调用:
$("#text").load(".../ajax_response.php?_ajax_nonce=<?php echo $nonce ?>");
最后在 ajax_response.php
函数中使用 check_ajax_referer()
函数进行验证:
check_ajax_referer('wpjam');
举个详细的例子,比如统计微信分享的 AJAX 代码中:
var nonce = <?php echo wp_create_nonce( 'weixin_robot' ) ?> jQuery.ajax({ type: "post", url: ajax_url, data: { action: 'weixin_share', share_type: share_type, post_id: post_id, link: link, _ajax_nonce: nonce }, success: function(html){ alert(html); } });
服务器处理代码:
check_ajax_referer( "weixin_robot" );
评论 (0)