| 字段 | 详情 |
|---|
| CVE | CVE-2026-16540 |
| 插件 | Simply Schedule Appointments |
| 受影响版本 | < 1.6.12.6 |
| 修复版本 | 1.6.12.6 |
| 活跃安装量 | ~70,000 |
| CVSS 3.1 | 6.5(中危)— CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N |
| CWE | CWE-863(不正确的授权) |
| OWASP | A5:失效的访问控制 |
| WPVDB | c3829294-c388-4151-9e25-a3eac7b1f1c6 |
| 研究人员 | Suleyman Huseynov(@huseyn0vs__) |
| 披露日期 | 2026-07-22 |
Simply Schedule Appointments 中的 GET /wp-json/ssa/v1/appointments/purge REST 端点应用了授权检查(get_items_permissions_check),该检查验证一个 id_token 以证明对单个预约的所有权。然而,处理函数(purge_appointments())完全忽略了该令牌所属的预约,而是操作整个站点中满足给定条件的所有预约。
未经过身份验证的攻击者通过公共预约表单预约任意一个预约后,会收到一个 id_token。使用该令牌,攻击者可以:
删除操作会在已提交的事务中级联影响 6 个依赖数据库表,且没有原生的撤销功能。
文件: includes/class-appointment-model.php
权限检查与处理函数的作用域完全不同:
// 路由注册
register_rest_route( $namespace, '/' . $base . '/purge', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'purge_appointments' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
),
) );
权限检查 — 通过 id_token 验证对一个预约的所有权:
public function get_items_permissions_check( $request ) {
// ...
if ( true === $this->id_token_permissions_check( $request ) ) {
return true; // 如果调用者证明了对一个预约的所有权,则授予访问权限
}
// ...
}
处理函数 — 忽略令牌对应的预约,进行站点级操作:
public function purge_appointments( WP_REST_Request $request ) {
$params = $request->get_params();
// 没有 customer_id 或 appointment_id 的作用域限制——删除所有匹配的预约
if ( isset( $params['purge_past_appointments'] ) && 'true' === $params['purge_past_appointments'] ) {
$conditions[] = $wpdb->prepare( 'end_date < %s', $date_modified_max->format( 'Y-m-d' ) );
}
$sql = 'SELECT * FROM ' . $this->get_table_name()
. ' WHERE ' . implode( ' OR ', $conditions )
. ' ORDER BY id ASC LIMIT 5000';
$list = $wpdb->get_results( $sql, ARRAY_A );
// 在已提交的事务中级联删除 6 个表
}
id_token 是由单个预约的 id 和 date_created 通过 HMAC-MD5 派生而来。拥有此令牌仅证明调用者预约了某个特定预约——它不赋予任何站点级权限。
1. 攻击者访问预约页面并预约任意免费预约
→ 收到确认邮件,包含:appointment_id + id_token
2. GET /wp-json/ssa/v1/appointments/purge
?id=<appointment_id>
&token=<id_token>
&purge_past_appointments=true
3. 权限检查通过(令牌对于攻击者自己的预约有效)
4. 处理函数选择站点中所有过去的预约 → 在响应中返回个人身份信息
→ 永久删除这些预约(在高级版中跨越 6 个表)
PoC 将于 2026-08-05 发布,遵循协调披露禁令。
在禁令日期后请参阅 poc/ 目录。
| 场景 | 结果 |
|---|---|
| 数据泄露 | 所有客户的姓名、邮箱、电话号码、预约详情 |
| 批量删除(高级版) | 所有历史/未来预约在 6 个表中被永久销毁 |
| 无恢复途径 | 需要完整数据库备份恢复 |
| 日期 | 事件 |
|---|---|
| 2026-07-10 | 发现漏洞 |
| 2026-07-10 | 提交至 WPScan |
| 2026-07-22 | 分配 CVE-2026-16540 |
| 2026-07-22 | 在 WPScan 上公开披露 |
| 2026-08-05 | PoC 发布 |