在开源 CMS 的世界里,Drupal 安全是少数几个公开流程好过平台名声的领域之一。Drupal 安全团队按固定的披露时间表运作,用一套有据可查的数值标准为每一份公告评分,并在核心与数以万计的贡献项目之间协调修复。
现实中的战绩配不上这套流程。Drupal 站点确实会被攻破,而原因几乎从来不是没有人知道。公告准时发布了,就在某个星期三。补丁则在下一周才进入生产环境。这篇文章要谈的正是那段空档,而安全加固、防火墙与文件权限的存在,都是为了让这段空档变得可以熬过去,或者把它缩短。
决定风险的是你打补丁的速度,而不是你恰好装了哪些模块。 核心公告落在每月一次的星期三窗口,贡献项目公告则是每周三,两者都依据一套公开的标准评为 0 到 25 分。极其严重的核心缺陷曾在披露后数小时内即遭利用:2014 年那份 SQL 注入公告发布后,官方指引是把任何在七小时内没有打上补丁的站点直接当作已被攻破。一个无法在一个工作日内部署核心补丁的站点,几乎承担了全部存在的风险。
Drupal 安全公告流程实际是怎么运作的
多数运营 Drupal 站点的人从没读过这些流程文档,这很可惜:文档明明白白写着你能得到多少预警、以什么形式、在哪几天。
发布窗口
安全团队照日历发布。贡献项目公告每周三发出。核心在每月第一个星期三有缺陷修复与功能发布窗口,第三个星期三则是安全发布窗口,安全发布时间的文档对此有明确规定。窗口并不承诺一定会有东西发布,它存在的意义是让管理员知道该盯住哪几天。
偶尔会有提前通知。在一次极其严重的核心发布之前,团队可能会发布一则公共服务公告,通常在星期一。PSA-2026-05-18 就是为 2026 年 5 月 20 日的发布这么做的,点明了 17:00 到 21:00 UTC 的窗口,并要求站点所有者先把自己所在分支更新到最新的补丁版本,好让升级问题提早暴露。两天,就是你能拿到的最长预警。
核心公告与贡献项目公告
这是两套保证程度不同的机制。核心公告覆盖受支持的次要分支,一次两条,最新的一条加上前一条。按照核心发布时间表,实际上就是 11.4.x 与 11.3.x,而在 Drupal 10 于 2026 年 12 月 9 日走到生命周期终点之前,10.6.x 仍在覆盖范围内。截至 2026 年 9 月初,当前版本是 11.4.5、11.3.16 与 10.6.15。Drupal 12.0.0 与 11.5.0 预定在 2026 年 12 月 7 日那一周发布,届时 11.3.x 与 10.6.x 的支持随之结束。
贡献项目的覆盖是自愿加入且附带条件的。只有在安全公告流程与权限政策之下,由维护者主动申请并获得批准的项目,其受支持主要分支上的稳定版本,才会有公告。处于 alpha、beta 或候选发布版本的模块落在这套体系之外,维护者从未申请过的模块也一样。站点正常运行时,这两件事在管理界面上都看不出来。
真正的工作量在于数量。2026 年 8 月 26 日星期三,团队一天之内发布了十份贡献项目公告,全部为中等严重。一个跑着六十个模块的站点,一年会被点名好几次,而这条持续不断的细流,长期成本高过核心那几次紧急事件。
风险评分,以及它为什么不是 CVSS
每一份公告都带一个满分 25 的数字。这套标准基于 NIST 的通用误用评分系统,即 NISTIR 7864,并记录在安全风险等级说明页上。六项指标构成输入:攻击复杂度、所需认证、机密性影响、完整性影响、是否存在已知利用代码,以及目标分布。分段为:不严重 0 到 4,较低严重 5 到 9,中等严重 10 到 14,严重 15 到 19,极其严重 20 到 25。
正因为目标分布计入评分,只在少见配置下才会咬人的缺陷,得分会低于它在 CVSS 下应有的水平。2026 年 6 月 17 日的 SA-CORE-2026-005 是一个以 CVE-2026-55803 追踪的 PHP 对象注入问题,得 18 分,正是由于这个原因被评为严重而非极其严重。
贡献模块被标记为不再受支持时
安全团队无法强迫一位志愿维护者修复任何东西。当维护者不再回应,记录在案的流程是在反复尝试联系之后,把项目标记为不再受支持。项目页面随即会提醒站点所有者:改用一个仍在积极维护的替代品,或者出钱请人修好这个缺陷,让模块可以重新发布。
这条建议正确,而且昂贵,因为等到一个模块被标记为不再受支持时,它通常已经是承重结构,替换它意味着数据迁移、模板改动和一整轮回归测试。真正便宜的时机是被放弃之前的那一次发布,维护者已经沉默但还没有任何东西损坏的时刻,而那时几乎没有人在看。
Drupal 7 已经终止支持,而延长支持不等于安全
Drupal 7 已于 2025 年 1 月 5 日走到生命周期终点,PSA-2025-01-06 对此做了确认。从那天起,安全团队停止为 Drupal 7 核心及其贡献模块与主题提供支持和公告。公告明确写道,Drupal 7 的安全问题此后可能在没有任何协调的情况下被公开披露,零日漏洞也可能出现。
商业延长支持市场是存在的。Drupal 协会在延长安全支持提供商计划之下认证了若干厂商,包括 HeroDevs 与 Tag1 Consulting,它们确实会产出补丁。这比什么都没有要好,但不等同于受支持。厂商按自己的时间表,为付费客户修补核心和一组它自己选定要覆盖的模块。你的站点所依赖的生态系统其余部分,不在范围内。
一个不再受支持的 CMS,在供应商保障问卷上难以交代,事故之后面对保险公司同样难以交代。我们关于 Drupal 迁移的成本、选项与期限的指南,写清了退出这条路要花多少钱。
历史留下的模式:Drupalgeddon 及其后续
三起事件塑造了社区对打补丁速度的看法。每一起都是核心中的注入或远程代码执行缺陷,每一起都在数小时到数天内引来了大规模自动化利用。
2014 年 10 月的七小时窗口
最初的 Drupalgeddon 是 SA-CORE-2014-005,发布于 2014 年 10 月 15 日。CVE-2014-3704 是 Drupal 7 数据库抽象层中的一个 SQL 注入缺陷,匿名用户即可利用,拿到了满分 25 分中的 25 分。所有低于 7.32 的 Drupal 7 站点都受影响。
真正让它成为里程碑的是后续通告。PSA-2014-003 告诉站点所有者,自动化攻击在公告发出后数小时内就开始攻陷未打补丁的站点,并且他们应当假定任何在当天 23:00 UTC,也就是发布后七小时之前没有打上补丁的站点,已经被攻破。不是可能被攻破,是已经被攻破。通告还警告攻击者可能已经取走全部数据并植入后门,正是这一点把打补丁的问题变成了事件响应的问题。
Drupalgeddon 2 与 3
发布于 2018 年 3 月 28 日的 SA-CORE-2018-002 即 CVE-2018-7600,是一个横跨 Drupal 7 与 Drupal 8 多个子系统的远程代码执行缺陷,得 25 分中的 24 分。它影响 Drupal 7.0 到 7.57,以及 8.5.0 之前的各条 8.x 分支,公开的利用代码在大约两周内出现。
四周之后,SA-CORE-2018-004 于 2018 年 4 月 25 日落地。CVE-2018-7602 是相关代码里的另一个远程代码执行问题,得 25 分中的 20 分,而公告明确写着它已经在野外被利用。教训在于这段间隔:三月打了补丁然后不再留意的站点,四月又一次暴露。
2026 年 5 月,以及没有改变的事
这套模式并不是历史。SA-CORE-2026-004 发布于 2026 年 5 月 20 日:CVE-2026-9082 是一个影响 PostgreSQL 上站点的 SQL 注入缺陷,被评为极其严重的 25 分中的 23 分,覆盖从 8.9 一直到 11.3.9 的所有分支。5 月 22 日 04:30 UTC,该公告被修订,记录了在野外检测到的利用尝试,从发布到观察到攻击不足 48 小时。
这些都不是在批评安全团队。他们给了两天预警,在宣布的窗口内发布,并在情况变化时更新了公告。失效的一端在运营方:从公告到一个已打补丁的生产站点之间,没有一条演练过的路径。
Drupal 安全在实践中真正失守的地方
核心拿走了所有头条,却是其中最小的一环。在我们审计的站点里,真正要紧的发现很少是一个没打补丁的核心版本,因为核心更新会出现在管理界面上,总有人会注意到。风险敞口在别处。
没人拥有的模块清单
一个典型的中型 Drupal 站点跑着四十到八十个贡献模块,每一个背后是不同的维护者和不同的节奏。几乎没有人能当场回答的问题是:其中哪些仍有活跃的维护者,哪些受公告政策覆盖,哪些已经两年没有一次提交。这份清单,做出来要花上一个下午。
没人认领的自定义模块
最常见的严重发现,是一个由已经离开的外包人员写下的自定义模块。它通常做着集成性质的事:一条 CRM 数据流、一个定制的表单处理器、一个支付回调。它是对着更老的 API 写的,没有测试,团队里没有人说得清它到底校验了什么。自定义代码按定义就在公告体系之外:不会有哪封星期三的邮件告诉你它含有 SQL 注入,而状态报告会把一切显示为最新。它需要和其他软件开发工作同样的评审纪律。
Drupal 底下的那一层
Drupal 是 PHP,而 PHP 版本按自己的时间表走到生命周期终点。一个站点完全可以在 CMS 层面补丁齐全,却跑在一个一年前就停止接收安全修复的 PHP 版本上,因为托管环境从来没有被纳入维护的对话。关于文件权限与所有权的指引,立足于一条原则:Web 服务器不得能够写入它自己执行的文件。然而许多站点仍以可写的代码目录运行,只因为这样让某个部署脚本更省事。
一个 Drupal 站点本该如何打补丁
答案很无聊,这正是它迟迟没有被落实的原因。没有任何工具能免去一条从公告到生产的演练过路径,而把它建起来一次,比第一次紧急事件便宜。
Composer 工作流
Drupal 8 之后的一切都是 Composer 项目。连同依赖一起更新核心包,然后应用数据库更新并重建缓存:
1composer update "drupal/core-*" --with-all-dependencies
2drush updatedb
3drush cache:rebuild
Drush 可以换成 update.php。前后都检查一次状态报告。重要的不是这几条命令,而是它们先在生产之外的某个地方跑过。
真的是一份副本的预发布环境
预发布环境只有在它映照生产时才有用:同一套模块、同一个 PHP 版本、一份近期的脱敏数据库。一个陈旧的预发布站点给出的绿色结果毫无意义,那比没有预发布环境更糟,因为它制造信心。
顺序是:把生产环境拉到预发布,应用更新,运行数据库更新,走一遍那些让站点具备商业价值的页面与表单,然后部署。有一条能用的流水线,这需要 45 到 90 分钟。没有的话,是一天半。
自动化,以及它的限度
自动化依赖更新最有帮助的地方,是贡献模块这条数量大、严重度低的细流。一个机器人为每次模块更新开一个拉取请求,并对每一个都跑一遍测试,就把每月一次的手工清扫变成了一条评审队列。核心也在往同一个方向走:自动更新的工作建立在 Package Manager 模块之上,该模块随核心一同发布,但仍处于实验阶段。
现实的时间预算
一个被认真维护的 Drupal 站点,例行模块更新大约每月花掉半天,再加上每一次适用的核心安全发布所需的一到三小时。还要为一年里那一两次必须当晚完成的极其严重发布留出余量。这就是多数内部团队从未编入预算的那个数字,也是这项工作总被推迟的原因。
打补丁之外的安全加固
安全加固不能替代打补丁。它减少的是已公开漏洞中在你这套安装上真正可被利用的数量,并在补丁无法立即发布时争取时间。那些 Drupal 特有的动作都很便宜,而且一劳永逸。
可信主机与文件系统
设置可信主机模式。Drupal 使用 Symfony 的可信主机机制,通过 settings.php 里的 trusted_host_patterns 配置,写成匹配站点对外应答域名的正则表达式。带有其他 Host 头的请求会被以 400 拒绝。没有它,攻击者可以用伪造的头污染密码重置链接和被缓存的绝对 URL。
任何不该被公开读取的东西都放进私有文件系统,并确保 PHP 不能在公开文件目录内执行。Drupal 自带一份 .htaccess 文件,在 Apache 下阻止执行,但 nginx 没有对应的放进去就生效的文件,规则必须手工写进服务器配置。多年前从 Apache 迁到 nginx 的站点,常常在无声无息中丢掉了这层保护。
然后套用所有权模型:目录 750,代码文件 640,文件目录只对 Web 服务器可写,settings.php 只对属主可读。
权限、管理路由与一次审查
限制管理路由。一个编辑人员只在三个办公室办公的站点,其登录与管理路径没有任何理由要对整个互联网开放,一份 IP 允许列表或一个带认证的代理,就能去掉一整类凭据攻击。
接着审计权限矩阵。它随着每装一个模块而生长,而发现的问题几乎总是同一个形状:一个能管理文本过滤器的编辑角色,或者一个能执行任意 PHP 的角色。两者都会把一个被盗的编辑密码变成远程代码执行,于是一封钓鱼邮件就成了服务器沦陷。
在争论其他任何事情之前,先跑一遍 Security Review 模块。它把那些手工做起来很烦的检查自动化了:文件系统权限、不安全的文本格式、内容里的 PHP 或 JavaScript、错误报告外泄、上传扩展名、失败登录、危险权限,以及可信主机配置。2026 年 1 月发布的 3.1.3 版本,除 Drupal 11 外还支持 Drupal 10.3 及以上。
防火墙能买到什么,又买不到什么
Web 应用防火墙是一种虚拟补丁,Drupal 协会正是这样定位它与安全团队共同运营的付费服务 Drupal Steward 的。它为某些极其严重的核心漏洞提供网络层缓解,在公告与部署之间的空档里保护站点。公开的定价是:每月处理 100 万次 HTTP 请求的站点低于 20 美元,超过 1000 万次的低于 100 美元。
限制由项目自己说明:并非每一个问题都能用这种方式缓解,而且这套机制只覆盖通过对 Web 服务器的请求被利用的漏洞。防火墙对一个被盗的管理员密码、一次恶意的模块更新,或者你自己代码里的一个缺陷,什么都做不了。把它当成打补丁窗口的保险,而不是把这个窗口拉长的理由,这也是我们在 WordPress 安全加固清单里持有的看法。
一次入侵的代价,以及恢复是什么样子
从一次 Drupal 入侵中恢复不是打个补丁。一旦攻击者取得代码执行,工作假设就是文件被写入、凭据被取走、持久化机制被安装,这正是安全团队在 2014 年告诉 Drupal 7 站点所有者的话。原地清理一个被攻破的站点,是披着修复外衣的猜测。
站得住脚的做法是:从版本控制在一台新主机上重建代码库,只在检查之后恢复内容与上传的文件,轮换站点持有过的每一份凭据,并保全而不是删除被攻破的磁盘镜像。最后这一步是人们在压力之下最常跳过的,而它是关于发生了什么的唯一证据。
商业代价很少来自重建本身,而是来自停机、取证工作、客户沟通与监管流程。事件条件下的一次重建,通常是 5,000 到 20,000 英镑的工程量,往往是总账里最小的一项。
英国的数据保护义务
如果个人数据已被或可能已被访问,UK GDPR 的时钟从你意识到的那一刻开始走,而不是从你查清楚的那一刻。ICO 的数据泄露指引要求,应报告的泄露必须毫不迟延地报告,且不得晚于意识到之后的 72 小时,若耗时更久则必须说明理由。当泄露很可能对个人的权利与自由造成高风险时,你还必须毫不迟延地通知这些个人。
ICO 说得很清楚:掌握的情况不完整,不是错过期限的理由,先报告你知道的,随后补充。在应当通报时未通报,可能招致最高 870 万英镑或全球营业额百分之二的罚款。
这个时钟正是取证问题为何要紧的原因。一个没有日志、也没有记录当时跑的是哪个版本的站点,说不清哪些数据被访问过,于是最后只能按最坏情况上报。这就是应当在事故之前而不是之后做一次网站安全审计的理由。
一份 Drupal 安全维护合约该包含什么
一份只承诺应用更新的维护合约不值得买,因为应用更新是容易的那一半。你真正付钱买的,是极其严重公告落地那天的响应路径,而证明它有效的交付物是一次演练。
值得付钱的范围包括:针对你确切模块清单的公告监控;带预发布、测试与回滚方案的月度补丁周期;针对极其严重核心发布的、约定好的非工作时间响应窗口;每季度一次的被放弃模块评审并给出替代方案的估价;PHP 与平台版本跟踪;以及一年一次的配置审查。
在英国,只做监控的安排大致是每月 250 到 450 英镑。包含预发布、测试与部署、面向中型站点的维护合约,则更接近每月 600 到 1,500 英镑,随模块数量与自定义代码体量而浮动,因为这两者决定了每个周期需要多少回归测试。对照 600 到 900 英镑的机构日费率,这个区间的上端大约买到两个工程师日。我们那篇关于 Drupal 开发者费率与甄别的文章里有具体数字。
关上那道空档
Drupal 给你的预警和结构,比几乎任何可比平台都多。公告按时间表发出,极其严重的发布带着两天预警抵达。可这一切都帮不了一个要花两周才能部署一行补丁的站点。
Mecanik 把 Drupal 的打补丁与安全加固,作为网站安全审计与持续软件开发工作的一部分来处理。第一次合作通常是一次盘点而不是一次修复,因为多数站点说不出自己的模块里还有哪些仍受支持。如果你还在权衡平台本身,我们的 2026 年 Drupal 网站开发指南谈的正是那个问题。
常见问题
Drupal 多久发布一次安全更新。 贡献项目公告每周三发布,Drupal 核心则在每月第三个星期三有一个安全发布窗口,不过窗口并不保证一定会有发布。极其严重的核心发布之前,通常会提前大约两天发出一则公共服务公告,点明日期与时间窗口。
Drupal 安全风险评分 25 分中的 20 分是什么意思。 Drupal 用一套基于 NIST 通用误用评分系统的方法,为每一份公告打出 0 到 25 分,综合考量攻击复杂度、所需认证、机密性与完整性影响、是否存在已知利用代码,以及受影响站点的数量。凡是得分在 20 到 25 之间的都属于极其严重,意味着当天就要打补丁。
2026 年还能安全地运行 Drupal 7 吗。 不能。Drupal 7 已于 2025 年 1 月 5 日走到生命周期终点,Drupal 安全团队不再为其核心、贡献模块或主题发布公告,因此缺陷可以在没有协调修复的情况下被公开披露。商业延长支持按厂商自己的条件覆盖一组限定的代码,它在迁移期间有帮助,但不等同于受支持。
攻击者利用一个 Drupal 漏洞有多快。 最坏的情况是几小时之内。2014 年 10 月那份 SQL 注入公告之后,Drupal 安全团队告诉站点所有者,应当假定任何在七小时内没有打上补丁的站点已经被攻破。2026 年 5 月,针对一个极其严重的核心 SQL 注入的利用尝试,在发布后不到两天就在野外被检测到。
有了 Web 应用防火墙,Drupal 还需要打补丁吗。 需要。像 Drupal Steward 这样的防火墙,为某些通过 Web 请求被利用的极其严重核心缺陷提供虚拟补丁,从而在部署窗口里争取时间。它帮不了被盗的管理员密码、被污染的模块或你自己代码里的缺陷,所以它降低的是这段空档的风险,而不是把空档关上。
评论