关于存在于WordPress 主题Argon中的越权修改漏洞

摘要

在Wordpress 主题Argon的1.2.9版本到1.3.5版本中,存在一个越权修改漏洞。该漏洞能让用户修改无权修改的文章meta信息。本文将会详细介绍这个漏洞的相关信息。

背景信息介绍

Argon主题,是一个在网上用户量较大的一个Wordpress 博客主题。项目在github的地址为:https://github.com/solstice23/argon-theme

在本文编写的时候(2026年4月21日),Argon主题最后的发布版本为1.3.5,该版本发布于2022年3月19日。我发现的这个漏洞影响1.2.9版本到1.3.5版本。

漏洞详情

在主题的源码文件functions.php中,有一个函数叫做update_post_meta_ajax,这个函数注册了下述两个接口

    add_action('wp_ajax_update_post_meta_ajax', 'update_post_meta_ajax');
    add_action('wp_ajax_nopriv_update_post_meta_ajax', 'update_post_meta_ajax');

这两个接口被用于在Wordpress 文章编辑页面中保存文章元信息相关的设置。

但是,这两个接口未仔细进行用户权限校验。相关的有缺陷代码如下

function update_post_meta_ajax(){
	if (!isset($_POST['argon_meta_box_nonce'])){
		return;
	}
	$nonce = $_POST['argon_meta_box_nonce'];
	if (!wp_verify_nonce($nonce, 'argon_meta_box_nonce_action')){
		return;
	}
	header('Content-Type:application/json; charset=utf-8');
	$post_id = intval($_POST["post_id"]);
	$meta_key = $_POST["meta_key"];
	$meta_value = $_POST["meta_value"];

	if (get_post_meta($post_id, $meta_key, true) == $meta_value){
		exit(json_encode(array(
			'status' => 'success'
		)));
		return;
	}

	$result = update_post_meta($post_id, $meta_key, $meta_value);

	if ($result){
		exit(json_encode(array(
			'status' => 'success'
		)));
	}else{
		exit(json_encode(array(
			'status' => 'failed'
		)));
	}
}

源代码地址

上述代码在执行操作的时候,鉴权阶段只校验了请求的nonce值,并未校验其他的各种用户权限信息。这样导致,只要恶意的已登陆用户能够获取到自身的nonce值,该用户就可以更改当前所有文章的部分meta信息(包括他本应该不能修改的文章的)。

影响范围以及后果

当您使用Wordpress 版本的Argon,且主题版本在1.2.9版本到1.3.5版本(本文发布的时候最新的release版本)之中。则可能会受到此漏洞的影响。但是此漏洞利用需要很多前置条件。

首先,如果恶意用户想要利用此漏洞,那么需要有以下的前置条件:

1、他在您系统中有一个注册了的账号,且能正常登陆

2、他的账号有权限访问Wordpress 的文章编辑界面(图1所示的界面),(只要能打开任意一个文章的编辑界面即可,无论是否有权直接发表)。

图1 wordpress 文章编辑界面
图1 WordPress 文章编辑界面

拥有上述条件之后,恶意用户便可以利用这个漏洞修改本来无权修改的文章的meta元信息。而且argon主题会给所有文章加上一个键名为argon_after_post的meta信息,且会将argon_after_post这个键对应的值的内容渲染在对应文章的页尾,展示给用户。这个值可以是一段html代码,恶意用户可以通过此方案给文章注入恶意js脚本,或网站添加恶意内容。

能被篡改的meta信息列表如表1所示。

能被修改的meta键该meta键值的用处造成的影响
argon_hide_readingtime该篇文章是否隐藏字数/预计阅读时间信息小,仅更改一些文章小细节
argon_after_post这个键储存了要展示的文末附加内容严重,可引入恶意脚本,添加恶意内容
argon_custom_css这个键储存了文章自定义Css中,能篡改网页部分页面内容样式
其他文章meta信息包含argon主题其他的键名以及任何其他插件在文章中留下的meta信息。具体可造成的影响取决于当前网站所安装的其他插件。

问题复现

下面是具体复现这个漏洞的方案。

获取nonce值

首先,登录之后,在对应站点的任意一个文章编辑界面,打开网页控制台[1],输入下面的指令,[2],输入后,nonce值会在终端显示出来,如图2所示。我们复制这个nonce值。

document.querySelector('#argon_meta_box_nonce')?.value
在火狐浏览器的控制台获取argon主题生成的nonce值
图2 在火狐浏览器的控制台获取argon主题生成的nonce值

获取当前登录用户的cookie

获取到nonce值后,我们还需要拷贝出Wordpress 当前的登陆了的cookie中的两个值,我们使用浏览器的开发者工具,找到当前网页的两个cookie,他们分别以wordpress_logged_in_xxxwordpress_sec_xxxx开头。

在火狐浏览器中,您只需要按F12 打开开发者工具后,点击储存页签 ,点击左侧Cookie栏目,选中当前站点,可以看到如图3中部圈出的数值,这就是我们需要的,复制键名与键值

在火狐浏览器开发工具中提取我们需要的cookie
图3 在火狐浏览器开发工具中提取我们需要的cookie

在Chrome(以及Edge等)浏览器中,可以通过打开开发者工具后。点击开发者工具的应用页签,在出现的左侧栏中找到Cookie项目,展开后选中当前站点,在右侧出现的值列表找到需要的两个值。如图4所示,也同样复制下来。

图4 在chrome开发者工具中找到我们需要的cookie值
图4 在chrome开发者工具中找到我们需要的cookie值

尝试修改当前登录用户有权限修改的文章信息

我们首先尝试一次修改当前用户有权限修改的文章meta信息。

在开始之前,Wordpress 文章编辑器中文章详情中的文末附加内容板块是空的。如图5所示。

图5 执行命令前

然后我们执行下述命令(在操作系统的终端中),其中 wordpress_logged_in_xxxxwordpress_sec_xxxxargon_meta_box_nonce换成我们刚刚获取的几个值,而post_id换成想要修改的文章id。(这个文章id可以在编辑器中地址栏目中获取,比如编辑器地址https://example.com/wp-admin/post.php?post=766&action=edit,那么文章id是766。

  curl.exe 'https://blog.q2019.net/wp-admin/admin-ajax.php' `
    -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' `
    -H 'Cookie: wordpress_logged_in_xxxx=xxxxx; wordpress_sec_xxxx=xxxxx;' `
    --data-raw 'action=update_post_meta_ajax&argon_meta_box_nonce=xxxx&post_id=766&meta_key=argon_after_post&meta_value=[SECURITY_TEST_SELF]'
执行命令后浏览器终端返回{"status":"success"}的截图
图6 执行命令后浏览器终端返回{"status":"success"}的截图

执行后。可以看到如图6所示返回了{"status":"success"},查看Wordpress 的文章内容编辑器,如图7,可以看到文末附加内容部分已经被添加了 [SECURITY_TEST_SELF] 字样。

图7 执行命令后 WordPress 文末附加内容

到目前为止,一切正常,用户有权修改自己有权限修改的文章的meta信息。但是,当我们将文章id换成当前用户无权修改的文章id,那么情况就不一样了。

尝试越权修改文章信息

我们首先找一个当前用户无权修改的文章id。

这里提一下,如何查看Wordpress 的文章的id。Wordpress 提供了诸多API接口[3]。其中有一个接口就可以获取到文章的详情信息(无需鉴权)。接口地址:

https://wordpress.example.com/wp-json/wp/v2/posts?page=1&per_page=10

其中参数page=1是页数,per_page=10是每页多少个,返回数据如图8所示。可以看到在这里可以获取到所有公开了的文章的文章id。

使用wp-json 的API获取文章列表并从中找出文章id的截图
图8 使用wp-json 的API获取文章列表并从中找出文章id的截图

获取到某个文章的id后。如果这个文章无权限编辑,直接使用Wordpress 文章编辑器打开此文章id,会出现如图9所示被拒绝的界面。

使用wordpress文章编辑器打开无权编辑的文章id后的截图
图9 使用Wordpress 文章编辑器打开无权编辑的文章id后的截图

此时页脚是没有任何内容的,如图10

执行越权指令前文章预览的截图
图10 执行越权指令前文章预览的截图

此时我们将刚刚执行的命令中的post_id=766改为这个文章id,并重新执行。可以看到如图11所示,命令成功执行。

执行越权指令后返回{"status":"success"}的截图
图11 执行越权指令后返回{"status":"success"}的截图

此时查看相应的网页,页尾被加上了[SECURITY_TEST_SELF] 这个字样,被越权修改了信息,如图12。

执行越权指令后文章页尾被添加内容的截图
图12 执行越权指令后文章页尾被添加内容的截图

我该如何避免因此受到影响?

由于此漏洞需要一些前置条件(条件已在前文中写明),所以利用条件较为苛刻。大部分个人站长不会受到此漏洞影响。但是如果很不幸,您在受影响的范围中的话,您可以按照下述方案修补。

我发现这个漏洞的时候(本博文发布的2个星期前),我已经邮件告知了主题作者,作者大大也对此问题进行了回信,如图13。作者在当天在https://github.com/solstice23/argon-theme/pull/705这个提交中对此问题进行了修复。

作者大大关于此漏洞的回信
图13 作者大大关于此漏洞的回信

但是由于当前主题是处于非积极维护的状态,所以此补丁的修复版本并没有作为release版本进行发布。所以我们如果需要,前往项目github页面,下载主题文件并进行替换即可。

参考

  1. ^注,这里指的是网页控制台,而不是系统终端。大部分浏览器可以通过按F12按钮打开开发者工具,在开发者工具打开控制台
  2. ^部分浏览器首次复制指令到网页终端可能需要一些授权,具体操作取决于测试用的浏览器

--------------

本文标题为:

关于存在于WordPress 主题Argon中的越权修改漏洞

本文未经许可,请勿以任何形式转载于任何其他站点、平台,谢谢。
上一篇