mcpField
F
fix-php-vuln

fix-php-vuln

github.com/cognitionai安全1012 次安装6 天前更新
代码仓库

关于 fix-php-vuln

fix-php-vuln 是供 Agent 使用的安全修复技能,用于查找受 PHP2Shell 影响的 PHP 运行时并修补获批仓库。它先只读盘点并等待审批,再通过测试和产物检查验证修复版供应商构建,并准备专项 PR。

主要功能

  1. 01只读盘点 PHP 部署
  2. 02将构建分类为脆弱、已修复或未知
  3. 03选择并确认含修复的供应商版本
  4. 04测试并比较构建后的运行时产物
  5. 05准备专项 PR 和发布指导

适用场景

  1. 01查找仓库中对外服务的 SAPI 和 PHP 版本
  2. 02将获批部署更新到含修复的供应商构建
  3. 03评估旧版 PHP 分支及可用升级路径
  4. 04部署前检查测试结果和运行时变化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/cognitionai/devin-vuln-fixes --skill fix-php-vuln

安装后在 Claude Code 中输入/fix-php-vuln确认已加载。

详细介绍

修复 PHP 漏洞(PHP2Shell,CVE-2026-109618 / CVE-2026-109619)

概述

查找并修复受 PHP2Shell 影响的 PHP 运行时:这两个严重漏洞(CVSS v4 9.2)可在未认证的情况下实现远程代码执行(RCE),并已于 2026-10-21 在 8.2.35、8.3.36、8.4.27 和 8.5.12 中修复。PHP 8.1 及更早版本也受影响,但不会发布新版本,只有源代码回移补丁。PHP 表示,所有用于提供 Web 服务的 SAPI 都面临风险(mod_php 风险最高,此外还包括 FPM、php-cgi、FrankenPHP 和 LiteSpeed)。也应将内置的 php -S 服务器视为存在暴露风险,并标明它不适用于生产环境。首先只进行只读盘点。编辑前等待批准。将每个获批的仓库升级到供应商已修复的构建版本,验证构建产物,并创建范围明确的 PR。升级是唯一彻底的修复方案。

需要用户提供的信息

  • 要扫描的仓库或组织。默认:用户指定的仓库,或 Agent 能访问的所有仓库。
  • 批准要修补的已发现仓库,以及任何次版本/主版本升级、基础操作系统变更或可能涉及应用代码变更的操作。
  • 验证目标并运行构建所需的注册表、软件包镜像源和 CI 访问权限。

流程

  1. 克隆之前,先使用 Git 托管平台的代码搜索功能,以只读方式搜索所有可访问的仓库(如果没有代码搜索功能——这在 GitHub Enterprise Server 和自托管 GitLab 上很常见——则浅克隆并运行 rg -n --hidden --glob '!.git')。查找:
    • php: 镜像及其他 PHP 基础镜像。
    • php* 操作系统软件包(apt/apk/dnf)、setup-php CI 步骤,以及 PHP 源码下载和 ./configure 构建。
    • 安装 PHP 的 Helm、Kustomize、Terraform/Packer,以及 Ansible/Chef/Puppet 代码。
    • 作为使用信号的 composer.json/composer.lock 和 *.php。
    • 仓库的测试命令,以及已知会被目标次要版本破坏的代码(例如 8.2 中未声明的/动态属性、${} 插值、utf8_encode),以便门禁能显示升级风险。
  2. 生成一张清单表:仓库、文件:行号、信号、当前版本、渠道(官方镜像、发行版软件包、源码构建、托管平台)、精确/浮动/摘要锁定、SAPI、可判断时注明是否暴露于互联网、测试覆盖情况(无、有限、完整测试套件)以及置信度。另行列出无法搜索的仓库。
  3. 将每项标记为已修复、易受攻击或未知。对于发行版和托管平台构建,分别检查供应商的软件包变更日志或安全公告中是否修复了两个 CVE。切勿通过比较 php -v 与上游版本号来判断。
  4. 停止。展示表格并询问要修补哪些仓库。在同一条消息中询问是否允许升级次要/主要版本、变更基础操作系统以及可能的应用代码变更,以便提前一次性批准。发现阶段不要做任何更改。
  5. 按顺序逐个处理已批准的仓库。如果你的 Agent 支持子 Agent,则每个仓库运行一个,最多同时运行五个。编辑仓库之前,重新核查其清单。
  6. 对每个仓库,按路径选择最小的已修复目标版本,并在编辑前确认该版本存在。若公共主机被屏蔽,则检查仓库 CI 已使用的注册表或软件包镜像(Artifactory、Nexus、Harbor 或云注册表);如果两者都无法访问,则在 PR 中标记目标未经验证,并由 CI 构建验证。
    • 精确镜像标签:升级到同一次要版本中已修复的补丁版本,并保留变体(-fpm、-apache、-alpine、-bookworm 等)。
    • 摘要锁定:解析并锁定新的摘要。
    • 浮动标签:保留标签。要求使用 --pull --no-cache 重新构建并重新部署,并记录已验证的各平台摘要(标签重新推送时,索引摘要会变化)。说明标签的基础操作系统是否已变更(例如 bookworm → trixie)。
    • 占位符或无法解析的摘要:标记出来,因为实际部署的内容未知,并请用户确认正在运行的镜像。
    • 发行版软件包:通过供应商安全仓库升级,并记录软件包发行版本及其变更日志中的 CVE 条目。在 Dockerfile 中锁定已修复的发行版本,或在安装到更旧版本时让构建失败。在 Ansible/Chef/Puppet 中,state=present(或同等设置)绝不会升级现有主机:应使用 latest 或版本锁定,然后重启 PHP。
    • CI setup-php:它接受 major.minor,并安装运行器可获取的最新补丁版本,因此应设置 major.minor 并在 CI 日志中确认补丁版本。
    • 源码构建:切换到已修复的 tarball,验证 php.net 上公布的 SHA-256,并保留 configure 标志和扩展。对于 7.4/8.0/8.1,应改用 PHP 公布的回移提交(锁定提交哈希;没有 tarball 校验和),或在获得批准后改用受支持分支(第 8 步)。
    • Helm/IaC:修改实际选择制品的输入(镜像标签/摘要、AMI、软件包锁定),并重新生成锁文件或渲染输出。
  7. 保持 Composer require.php 和 config.platform.php 不变。它们不会选择已部署的运行时。
  8. 单独报告 PHP 8.1 及更早版本,并区分供应商支持的构建(例如 Ubuntu jammy 的 8.1,通过供应商软件包修复)和不受支持的构建(源码构建、已结束生命周期的镜像)。提供供应商回移或 PHP 回移方案,以及升级到受支持分支的路径。只有用户批准后,才升级次要/主要版本。
  9. 更改前后均测试回归:
    • 基线:编辑之前,构建当前制品(使用 --pull,记录其摘要作为回滚目标),并在该制品中运行仓库的测试(composer test、PHPUnit/Pest、make test 或 CI 测试命令)。官方 php: 镜像不含 Composer:运行脚本底层的命令,或使用仅额外安装 Composer 的临时镜像。记录结果,避免将既有失败归咎于升级。
    • 更改后:重新构建,并在新的生产镜像中运行相同测试,而不是在主机上运行。如果该镜像不含测试或开发依赖,则基于相同基础镜像构建测试阶段,或挂载测试文件。将新增失败、错误和弃用警告视为回归。
    • 比较运行时:对比新旧镜像的 php -m 和关键 php -i 值(ini 设置、ICU/OpenSSL/libxml 版本),并报告任何扩展、ini 或基础操作系统变更。
    • 冒烟测试:按生产环境的方式启动容器(FPM/Apache/CLI 入口点),请求健康检查或主要路由,并检查日志中的致命错误和弃用警告。还要检查响应正文和标头:当 display_errors 开启时(镜像没有 php.ini 时的默认设置),新增弃用警告会被打印到页面中,可能破坏 JSON 响应和标头。
    • 对于次要/主要版本升级(例如 8.1 → 8.2),还应在新镜像中运行 composer check-platform-reqs(若没有 composer.lock,先在临时副本中生成一个),以及 PHPCompatibility(phpcs --runtime-set testVersion)或 Rector dry-run,并列出适用的 UPGRADING 说明。优先使用目标 PHP 版本集的 Rector;PHPCompatibility 的稳定版早于 8.2。这些静态工具无法发现动态属性等运行时弃用问题,因此不能代替测试和冒烟测试。报告新镜像本身带来的扩展变更(例如,8.2 及以上版本的官方镜像移除了 ftp)。
    • 将每一步的输出保存为日志(基线、更改后、运行时差异、冒烟测试),并附在 PR 中。
    • 如果仓库没有测试(或测试很少)或无法构建,请醒目说明;使用仅补充缺失项的临时副本进行验证,并提出添加最小冒烟测试或特征测试的建议(未经批准不要提交)。
    • 确认制品版本(php -v / php-fpm -v,或镜像 SBOM)。对于发行版构建,还要确认已安装的软件包发行版本包含该修复。
    • 如果出现回归,先完成上述只读检查,然后停止并报告问题、失败输出以及在临时副本中验证过的最小修复方案。用户决定之前,不要提交版本升级。未经批准不要更改应用代码。
  10. 每个仓库开一个聚焦的 PR,列出各路径的更改前 → 更改后、摘要、需要重新构建的浮动标签、受阻项、生命周期已结束的项目、基线与更改后的测试结果、运行时差异和验证证据。标注风险:同一基础镜像上的补丁版本升级为低风险;次要/主要版本升级、基础操作系统变更或未经测试的仓库为高风险,并注明测试覆盖有限。提供发布计划:先部署到预发布环境或金丝雀环境,再使用上一版本的镜像摘要/软件包版本回滚。该回滚目标仍易受攻击,因此应同时采用下方的临时缓解措施。
  11. 将各仓库结果汇总到一张表中:仓库、PR、路径、更改前 → 更改后、修复证据、测试、受阻项、后续事项。提醒用户,只有部署并重启所有工作进程后,修复才会生效。

规格

  • 发现阶段只读,并在明确的批准关卡处结束。
  • 每个目标都要确认确实存在,且包含该修复,然后才能编辑。
  • 每个 PR 都要包含针对构建产物的验证,以及在镜像内部进行的修复前与修复后测试结果。
  • 完成意味着每个获批部署要么已验证修复,要么已报告为受阻,并附上明确的下一步。

建议与提示

  • 已知包含修复的回移版本(对于未列出的发行版,例如 Debian trixie 和 Ubuntu php8.5,请查看供应商跟踪器):
    • Debian bookworm 8.2.35-1~deb12u1。
    • Ubuntu noble 8.3.6-0ubuntu0.24.04.13。
    • Ubuntu jammy 8.1.2-1ubuntu2.28。
  • remirepo.net 当天没有更新。建议改用发行版软件包或从源码构建。
  • 临时缓解措施只能降低暴露风险:
    • 将 session.upload_progress.enabled=0 设置在 php.ini 或 FPM pool 中(不要使用 ini_set() 或 .user.ini),然后重启所有 worker。
    • 在 8.5 上,设置 fatal_error_backtraces=0。
    • 不允许上传时,将 post_max_size 设为 8M;允许上传时,设为 32M。
    • 限制代理的请求体大小、字段数量、多部分内容分段数量、标头数量和嵌套深度。
    • 设置 memory_limit=-1,并同时设置容器/cgroup 内存限制。
  • 内嵌 PHP 的设备和供应商产品需要供应商更新。请将其标记出来;不要就地打补丁。
  • 有人在 oss-security 上传播未经验证的说法,称 8.5.12 中的修复并不完整。推出更新前,请检查 PHP 安全公告(GHSA-w8hw-w9fx-j79w、GHSA-6wmf-4rv5-p3rp)是否有更新。

禁止的操作

  • 未经用户批准,不要编辑任何仓库。
  • 不要猜测镜像标签、摘要或软件包版本。
  • 不要将缓解措施说成修复。
  • 不要使用 RLIMIT_AS 或 RLIMIT_DATA 作为缓解措施。它们会触发易受攻击的内存分配失败。
  • 除非明确说明,否则不要更改 SAPI、基础发行版、镜像变体、扩展或构建标志。

评论

支持 Markdown