随机数
随机数是“使用一次的数字”,有助于保护 URL 和表单免遭某些类型的滥用、恶意或其他形式的滥用。
从技术上讲,WordPress 随机数并不是严格意义上的数字;而是数字。它们是由数字和字母组成的哈希值。它们也不是只使用一次:它们的“寿命”有限,之后就会过期。在此时间段内,将为给定上下文中的给定用户生成相同的随机数。该操作的随机数对于该用户将保持不变,直到该随机数生命周期完成。
WordPress 的安全令牌被称为“随机数”(尽管与真正的随机数存在上述差异),因为它们的用途与随机数几乎相同。它们有助于防范包括 CSRF 在内的多种类型的攻击,但不能防范重放攻击,因为它们不会被检查为一次性使用。切勿依赖随机数进行身份验证、授权或访问控制。使用 保护您的函数current_user_can()
,并始终假设随机数可能会受到损害。
为什么要使用随机数?
有关使用随机数的示例,请考虑管理屏幕可能会生成这样的 URL,该 URL 会丢弃帖子编号 123
http://example.com/wp-admin/post.php?post=123&action=trash
当您访问该 URL 时,WordPress 将验证您的身份验证 cookie 信息,并且如果您被允许删除该帖子,则将继续删除它。攻击者可以利用此漏洞让您的浏览器在您不知情的情况下访问该 URL。例如,攻击者可以在第 3 方页面上制作一个伪装链接,如下所示:
<img src="http://example.com/wp-admin/post.php?post=123&action=trash" />
这将触发您的浏览器向 WordPress 发出请求,浏览器会自动附加您的身份验证 cookie,并且 WordPress 会认为这是一个有效的请求。
添加随机数可以防止这种情况发生。例如,当使用随机数时,WordPress 为用户生成的 URL 如下所示:
http://example.com/wp-admin/post.php?post=123&action=trash&_wpnonce=b192fc4204
如果有人试图在没有 WordPress 生成并提供给用户的正确随机数的情况下删除编号 123 的帖子,WordPress 将向浏览器发送“403 Forbidden”响应。
创建随机数
您可以创建一个随机数并将其添加到 URL 中的查询字符串中,也可以将其添加到表单中的隐藏字段中,或者可以通过其他方式使用它。
对于要在 AJAX 请求中使用的随机数,通常将随机数添加到隐藏字段,JavaScript 代码可以从中获取它。
请注意,随机数对于当前用户的会话是唯一的,因此如果用户异步登录或注销,页面上的任何随机数将不再有效。
为访客(非登录用户)自定义随机数
默认情况下,WordPress 核心会为具有相同用户 ID(值 0
)的访客生成相同的随机数。也就是说,它不能阻止访客遭受 CSRF 攻击。为了增强关键操作的安全性,您可以为访客开发会话机制,并挂钩 nonce_user_logged_out 过滤器,以将用户 ID 值替换 0
为会话机制中的另一个随机 ID。
将随机数添加到 URL
要将随机数添加到 URL,请调用wp_nonce_url()
指定裸 URL 和表示操作的字符串。例如:
$complete_url = wp_nonce_url( $bare_url, 'trash-post_'.$post->ID );
为了获得最大程度的保护,请确保表示操作的字符串尽可能具体。
默认情况下,wp_nonce_url()
添加一个名为 的字段_wpnonce
。您可以在函数调用中指定不同的名称。例如:
$complete_url = wp_nonce_url( $bare_url, 'trash-post_'.$post->ID, 'my_nonce' );
向表单添加随机数
要将随机数添加到表单,请调用wp_nonce_field()
指定表示操作的字符串。默认情况下wp_nonce_field()
生成两个隐藏字段,一个的值为随机数,另一个的值为当前 URL(引荐来源网址),并且它会回显结果。例如,这个调用:
wp_nonce_field( 'delete-comment_'.$comment_id );
可能会回显类似的内容:
为了获得最大程度的保护,请确保表示操作的字符串尽可能具体。
您可以为 nonce 字段指定不同的名称,您可以指定您不需要引用字段,并且您可以指定您希望返回结果而不是回显。有关语法的详细信息,请参阅:wp_nonce_field()
。
创建一个随机数以其他方式使用
要创建以其他方式使用的随机数,请调用wp_create_nonce()
指定表示操作的字符串。例如:
$nonce = wp_create_nonce( 'my-action_'.$post->ID );
这只是返回随机数本身。例如:295a686963
为了获得最大程度的保护,请确保表示操作的字符串尽可能具体。
验证随机数
您可以验证在 URL、管理屏幕中的表单、AJAX 请求或其他上下文中传递的随机数。
验证从管理屏幕传递的随机数
要验证在管理屏幕中的 URL 或表单中传递的随机数,请调用check_admin_referer()
指定表示操作的字符串。
例如:
check_admin_referer( 'delete-comment_'.$comment_id );
此调用检查随机数和引荐来源网址,如果检查失败,则采取正常操作(使用“403 Forbidden”响应和错误消息终止脚本执行)。
如果您在创建随机数时未使用默认字段名称 ( _wpnonce
),请指定字段名称。
例如:
check_admin_referer( 'delete-comment_'.$comment_id, 'my_nonce' );
验证 AJAX 请求中传递的随机数
要验证 AJAX 请求中传递的随机数,请调用check_ajax_referer() 并指定表示操作的字符串。例如:
check_ajax_referer( 'process-comment' );
此调用检查随机数(但不检查引用者),如果检查失败,则默认情况下它会终止脚本执行。
如果您在创建随机数时未使用默认字段名称(_wpnonce
或)之一,或者如果您想采取其他操作而不是终止执行,则可以指定其他参数。_ajax_nonce
详细信息请参见:check_ajax_referer()
。
验证在其他上下文中传递的随机数
要验证在其他上下文中传递的随机数,请wp_verify_nonce()
调用指定随机数和表示操作的字符串。
例如:
wp_verify_nonce( $_REQUEST['my_nonce'], 'process-comment'.$comment_id );
如果结果为 false,则不再继续处理该请求。相反,采取一些适当的行动。通常的操作是调用wp_nonce_ays()
,它会向浏览器发送“403 Forbidden”响应。
修改nonce系统
您可以通过添加各种操作和过滤器来修改随机数系统。
修改随机数生存期
默认情况下,随机数的生命周期为一天。此后,即使随机数与操作字符串匹配,随机数也不再有效。要更改生命周期,请添加一个 nonce_life 过滤器,指定生命周期(以秒为单位)。
例如,要将生命周期更改为四小时:
add_filter( 'nonce_life', function () { return 4 * HOUR_IN_SECONDS; } );
执行额外验证
check_admin_referrer()
要在发现随机数和引荐来源网址有效时执行附加验证,请添加check_admin_referer
操作。
例如:
function wporg_additional_check ( $action, $result ) {
...
}
add_action( 'check_admin_referer', 'wporg_additional_check', 10, 2 );
以同样的方式check_ajax_referer()
添加一个动作。check_ajax_referer
更改错误消息
您可以使用翻译系统更改随机数无效时发送的错误消息。例如:
function my_nonce_message ($translation) {
if ($translation === 'Are you sure you want to do this?') {
return 'No! No! No!';
}
return $translation;
}
add_filter('gettext', 'my_nonce_message');
附加信息
本节包含有关 WordPress 中的随机数系统的其他信息,这些信息有时可能有用。
随机数生命周期
请注意,正如 WordPress 随机数不是“使用一次的数字”一样,随机数生命周期也不是真正的随机数生命周期。WordPress 使用具有两个刻度(生命周期的一半)的系统,并验证当前刻度和最后一个刻度的随机数。在默认设置(24 小时生命周期)中,这意味着随机数中的时间信息与自 Unix 纪元以来经过了多少个 12 小时时间段相关。这意味着在中午和午夜之间创建的随机数将具有生命周期,直到第二天中午。因此,实际寿命在 12 至 24 小时之间变化。
当随机数有效时,验证随机数的函数将返回当前刻度编号 1 或 2。例如,您可以使用此信息来刷新第二个刻度中的随机数,以便它们不会过期。
随机数安全性
如果您正确安装了 WordPress,则使用您网站特有的密钥和盐生成随机数。NONCE_KEY
和NONCE_SALT
在您的文件中定义wp-config.php
,并且该文件包含提供更多信息的注释。
切勿依赖随机数进行身份验证或授权或访问控制。使用 保护您的函数current_user_can()
,始终假设随机数可能会受到损害。
更换随机数系统
构成随机数系统的一些函数是可插入的,以便您可以通过提供自己的函数来替换它们。
要更改管理请求或 AJAX 请求的验证方式,您可以替换check_admin_referrer()
或check_ajax_referrer()
,或两者都替换。
要将随机数系统替换为其他随机数系统,您可以替换wp_create_nonce()
,wp_verify_nonce()
和wp_nonce_tick()
。
有关的
随机数函数:wp_nonce_ays()
, wp_nonce_field()
, wp_nonce_url()
, wp_verify_nonce()
, wp_create_nonce()
, check_admin_referer()
, check_ajax_referer()
,wp_referer_field()
随机数挂钩:nonce_life
, nonce_user_logged_out
, explain_nonce_(verb)-(noun)
,check_admin_referer
无评论