创建nonce并将其输出为数据属性是否存在漏洞


Is it a vulnerability to create a nonce and output it as a data-attribute?

我在WordPress网站上有一个静态项目列表,当用户悬停在每个项目上时,该网站会使用Ajax+通过PHP查询WordPress数据库在其他地方加载新数据。

在列表中,我让每个项目都有自己创建的nonce(使用wp_create_nonce())作为属性,以及所需的其他相关动态数据位(如类别id),因此最终的HTML看起来像这样:

<li data-nonce="abc" data-category-id="1">Option A</li>
<li data-nonce="def" data-category-id="2">Option B</li>
<li data-nonce="ghi" data-category-id="3">Option C</li>

然后在Javascript中,我做了这样的事情(当然缩短了):

on li hover {
var nonce = hoveredLi.attr('data-nonce'),
    catid = hoveredLi.attr('data-category-id');
$.ajax({ type : "GET", data : { action: 'the_function', nonce: nonce, catid: catid }.....

然后在PHP中,我通过确认nonce来启动ajax函数:

function the_function() {
  if ( ! wp_verify_nonce( $_GET['nonce'], 'nonce' ) ) {
    die();
  }
  $cat_id = isset( $_GET['catid '] ) && $_GET['catid '] ?  intval($_GET['catid '] ) : 0;
  $qry = new WP_Query( 'cat' => $cat_id, );
  // rest of function ....
}

这是确保ajax调用安全的正确方法吗?或者nonce如此容易可见(data-none属性)是否需要更改?

如果黑客试图使用开发工具更改nonce中的数据,它总是会失败吗?

如果黑客试图通过类别ID属性注入恶意代码,那么使用Intval是清除类别ID的最佳方法吗?类别总是整数,那么这是最有效的方法吗?

WordPress nonce只是为了防止CSRF。有人可以使用任何数量的方法修改nonce(隐藏它毫无意义),但nonce是特定于用户的,所以他们只会使其无效

除了验证nonce以确保用户实际执行了操作之外,只需确保您还验证用户是否具有在AJAX处理程序中执行该操作的适当权限。nonce并不验证用户是否有权执行某个操作,只是验证用户是否有意执行了该操作

例如,如果您的AJAX处理程序允许用户编辑帖子,那么您可能希望这样做。

if ( ! current_user_can( 'edit_posts' ) || ! wp_verify_nonce( $_GET['nonce'], 'nonce' ) ) {
    die();
}

至于您的另一个问题,请使用intval(int)将其强制转换为整数。

您可以安全地在代码中公开nonce,每个用户都会得到不同的nonce(这里有很好的解释)。随机数总是被加盐,这使得黑客"无法复制随机数"。intval将有效地净化cat输入。

在您的场景和"推荐实践"场景中,DOM理论上可以由最终用户修改,以表示未分配给他们的nonce。(Wordpress会检查指定的用户。)衡量风险。

然而,您所做的与将nonce添加到隐藏字段的推荐做法没有什么不同。如果用户可以以任何一种方式查看页面的当前HTML,它都是可见的,所以我认为你是安全的。