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日のカナダ勧告と矛盾します。この日付付き政府勧告を公開済みの運用指針として扱い、現在の提供状況と7.0の範囲をFortinetに確認してください。矛盾する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 アクセスの制限です。 | 証拠を保全し、一時対策を適用して指標を確認した後、更新と侵害調査を行ってください。 |
ステップ・バイ・ステップの攻撃フロー
ソースコード比較:脆弱 vs 堅牢化
FortiMail のファームウェアソースとベンダーの修正 diff は公開されていないため、これは一般的な 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画面の公開アクセスをなくして信頼できるプライベートネットワークに限定します。業務影響をメール担当者と調整します。[1]
- ✓再起動や更新の前にログ、設定バックアップ、フォレンジック証拠を保存します。FG-IR-26-175の最新IOCを確認し、一致を調査します。[1], [4]
- ✓公開済みのバージョン案内としてカナダ勧告AV26-989を使用し、更新前にFortinetの最新アドバイザリで提供状況とサポートを確認してください。CNAのより低い閾値は確認なしに使わないでください。[5], [1], [7]
- ✓更新と侵害調査を別々に実施します。修正版は以前に配置されたファイル、認証情報、永続化を消しません。不審な兆候があればインシデント対応を開始します。
- ✓独自のファイル処理では一度だけ厳格にデコードし、許可ルートに対する正規パス境界を検証し、NULと不正エンコードを拒否して信頼ディレクトリ相対で開きます。