必须通过Composer升级drupal/core至安全版本(如10.5.10或10.6.9),并执行drush cr清缓存,否则即使自定义模块已改用参数化查询,PostgreSQL驱动层的translateCondition()漏洞补丁仍不生效,CVE-2026-9082仍可被利用。

确认自定义模块是否真在用 db_query() 拼接用户输入
很多团队一看到“SQL注入”就急着改代码,但 Drupal 10 默认已禁用原始 db_query() 的动态拼接能力——除非模块显式调用并绕过参数化逻辑。先 grep 项目中所有 db_query(、db_select(、db_insert( 等调用,重点检查是否出现类似 db_query("SELECT * FROM {mytable} WHERE id = " . $_GET['id']) 这种字符串拼接。若只用了 db_select()->condition('uid', $uid) 或带占位符的 db_query("... WHERE status = :status", [':status' => $input]),则基本安全,无需修改。
替换 db_query() 字符串拼接为参数化查询
如果确实存在拼接行为,必须重写,不能加过滤函数“打补丁”。常见错误是只做 intval() 或 check_plain(),这对 PostgreSQL 数组键名注入(如 CVE-2026-9082)完全无效。
- 将
db_query("SELECT * FROM {node} WHERE title LIKE '%" . $_GET['q'] . "%'")改为db_query("SELECT * FROM {node} WHERE title LIKE :q", [':q' => '%' . $_GET['q'] . '%']) - 对多值 IN 查询,不要拼
"IN (" . implode(',', $ids) . ")",改用db_select('node')->condition('nid', $ids, 'IN')或db_query("... WHERE nid IN (:nids)", [':nids' => $ids])(Drupal 自动展开数组) - 若必须动态构建字段名(极少见),先白名单校验:
in_array($field, ['title', 'status', 'created'], TRUE),再拼进 SQL;绝不可放行用户传入的任意字符串
检查 JSON:API 或 Views 暴露的过滤器是否被模块二次处理
CVE-2026-9082 的典型入口是 JSON:API 的 filter[x][condition][value][MALICIOUS_KEY],如果自定义模块监听了 hook_jsonapi_resource_filter_alter() 或在 Views 中用 hook_views_query_alter() 手动解析 $view->getExposedInput() 并拼 SQL,就会复现漏洞路径。
- 搜索项目中是否调用
$_GET['filter']、$_REQUEST['filter']或直接读取$view->exposed_raw_input - 若存在,立刻替换为 Views 原生条件 API:
$query->addWhere(NULL, 't.field_name', $value, '='),而非"WHERE t.field_name = '" . $value . "'" - 特别注意 PostgreSQL 用户:任何使用
LIKE+ESCAPE或数组操作符@>的地方,都需验证escapeLike()是否被正确调用(它只在核心升级后才修复)
升级后仍触发注入?检查 vendor/ 是否被覆盖或缓存未清
即使模块代码已修复,若 vendor/drupal/core 仍是旧版,或 drush cr 没执行,PostgreSQL 驱动层的 translateCondition() 补丁就不会生效——攻击者仍可通过 JSON:API 绕过你写的参数化逻辑。
- 运行
composer show drupal/core,确认输出版本是10.5.10或10.6.9(不是composer.json里写的 ^10.5) - 检查
vendor/drupal/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php中是否存在对$key的正则校验(补丁关键行) - 强制重建缓存:
drush cr && drush sql:cli -c "SELECT pg_sleep(0.1)"测试是否还能触发时间盲注
真正危险的不是你写的那几行 db_query(),而是你以为修好了它,却忘了核心驱动层的补丁只随 Composer 升级落地——没升级 core,所有模块层的“修复”都是纸面防御。

















