flawopen.com/Teardowns/cve-2026-104286-fortimail-ibe-path-traversal
CVE-2026-104286:FortiMail IBE 路径穿越
CVE-2026-104286 可让未认证 HTTP(S) 请求通过路径穿越在易受影响的 FortiMail 系统写入文件。Fortinet 报告称漏洞正被利用;请禁用 IBE 或限制 Web 访问、调查设备并升级。[1], [5]
想象一个邮件收发室,工作人员负责归档附件。漏洞让请求提供误导性的文件夹路径,从而把文件写到预期区域之外。临时措施是关闭 IBE 入口或限制 Web 界面的访问,同时升级并检查此前是否有人进入。[1], [5]
核心概念与专有名词
框架映射
- 本指南所述弱点的 CWE 参考: CWE-22
- CISA KEV — 收录日期 2026-10-01 — CVE-2026-104286
根本原因剖析 (Root Cause)
Fortinet 将 CVE-2026-104286 描述为路径穿越漏洞,未认证 HTTP 或 HTTPS 请求可借此写入任意文件。FortiMail 固件为闭源,公开公告没有易受攻击的源代码行或补丁 diff;本文不编造这些细节。政府公告确认了任意文件写入影响、漏洞利用情况和版本建议,但没有说明 FortiMail 的内部处理程序。禁用 IBE 或限制 Web 访问的临时措施以及已发布的 IOC,应以 Fortinet 公告为准。请先限制并调查设备,再安装对应修复版本;未发现 IOC 不能证明设备安全。CVE 记录的文字描述列出 7.2.0–7.2.9、7.4.0–7.4.8、7.6.0–7.6.6 和 8.0.0–8.0.1。其结构化版本表为 7.4 和 7.6 列出更低的上限,并额外列出 7.0.0–7.0.9。该记录的解决方案部分又列出更早的“即将推出”版本 7.4.8、7.6.6、8.0.1 和 7.2.10,这与记录自身的受影响版本数据及 10 月 1 日加拿大公告冲突。请将这份有日期的政府公告作为已发布的操作依据,并向 Fortinet 确认当前版本可用性和 7.0 范围;不要从相互矛盾的 CNA 字段推断修复版本。[1], [3], [5], [4], [6], [7]
运维矩阵:版本范围与初步响应
| 范围 | 权威来源所述 | 防御者操作 |
|---|---|---|
| FortiMail 7.0 | NVD/CNA 数据列出 7.0.0–7.0.9;加拿大和法国的官方摘要未列出 7.0 分支。 同一记录的文字描述与结构化表格对 7.4 和 7.6 的上限也不一致。 解决方案部分还列出更早的“即将推出”版本(7.4.8、7.6.6、8.0.1 和 7.2.10),与受影响范围和加拿大公告冲突。 | 向 Fortinet 确认该分支状态;不要因摘要未列出就推断其安全。 |
| FortiMail 7.2 | 加拿大公告建议升级到 7.4 分支或更高版本。 | 规划迁移到已修复且受支持的分支;不要假定 7.2 有补丁。 |
| FortiMail 7.4 / 7.6 / 8.0 | 加拿大公告分别列出修复版本 7.4.9、7.6.7 和 8.0.2。 | 以加拿大公告 AV26-989 作为已发布的版本指导;升级前请在 Fortinet 当前公告中确认版本可用且受支持。未经确认不要采用 CNA 解决方案中较低的版本门槛。 |
| 遏制与调查 | Fortinet 报告了漏洞利用并发布入侵指标;临时措施是禁用 IBE 或限制 Web 访问。 | 保全证据,实施临时措施,检查厂商指标,随后修补并评估是否已遭入侵。 |
攻击执行流程分解
源代码对比:漏洞与安全实现
FortiMail 固件源代码和厂商补丁差异未公开,因此这是通用 Python 防护模式,并非 Fortinet 代码或漏洞复现。它只打开一次可信目录,使用服务器生成的不透明文件名,并相对于目录描述符以独占创建和禁止跟随链接的标志创建新文件。该模式仅适用于 POSIX;缺少所需标志时会安全失败。处理嵌套路径时,应通过目录描述符逐个遍历并验证组件;不要先检查字符串路径,再按名称重新打开。修复 CVE-2026-104286 应安装 Fortinet 支持的更新或应用其官方临时缓解措施。 配置的根路径及其所有父目录都必须由管理员控制;打开根路径时,O_NOFOLLOW 仅保护最后一个路径组件。
from pathlib import Path
def destination(root: Path, request_path: str) -> Path:
# 不安全设计示意:拼接请求输入后,
# 未检查路径是否仍在允许的根目录下。
return root / request_path
import os
import uuid
# 一次性打开服务的可信目录;其路径父目录必须由管理员控制。
def open_upload_root(root):
required = ("O_DIRECTORY", "O_NOFOLLOW")
if not all(hasattr(os, flag) for flag in required) or os.open not in os.supports_dir_fd:
raise RuntimeError("POSIX directory protections unavailable")
flags = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW
return os.open(root, flags)
# 不要把请求路径转换为文件路径;由服务器生成不透明名称。
# 名称已存在时 O_EXCL 会失败;O_NOFOLLOW 会拒绝末尾符号链接。
ROOT_FD = open_upload_root("/srv/app-private/uploads")
def create_upload_file():
name = uuid.uuid4().hex
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW
fd = os.open(name, flags, 0o600, dir_fd=ROOT_FD)
return name, fd
工程与系统安全加固清单
- ✓盘点 FortiMail 设备和版本。Fortinet 与政府摘要未列出 7.0,但 CNA 结构化数据列出 7.0.0–7.0.9;请向 Fortinet 核实该分支。[1], [5], [6]
- ✓立即实施厂商缓解:禁用 IBE,或移除 Web 界面的公网访问并限制到可信私网。与邮件团队评估禁用 IBE 的业务影响。[1]
- ✓重启或升级前保存日志、配置备份和取证证据。查看 FG-IR-26-175 当前 IOC,并调查任何匹配项。[1], [4]
- ✓以加拿大公告 AV26-989 作为已发布的版本指导;升级前请在 Fortinet 当前公告中确认版本可用且受支持。未经确认不要采用 CNA 解决方案中较低的版本门槛。[5], [1], [7]
- ✓将修补和入侵调查视为两项工作。修复版本不会清除之前放置的文件、凭据或持久化;发现可疑迹象时启动事件响应。
- ✓自有文件处理程序应在单次严格解码后对照允许根目录检查规范路径,拒绝 NUL 和无效编码,并相对于可信目录安全打开文件。