このプロジェクトと CVE-2026-86950 の詳細については、https://decalage.info/CVE-2026-86950/ を参照してください。
免責事項: この readme の大部分と検出コードは、AI コーディングエージェントの支援を受けて作成されました。このツールは、数千の正規 PDF ファイル、およびこちらで公開されている利用可能な概念実証に対して、成功裏にテストされています。 ただし、このツールは新しく、検出アルゴリズムはかなり複雑であるため、注意して使用してください。
detect_cve_2026_86950.py は、CVE-2026-86950(「The Great Glyph Grift」)を悪用するために細工された埋め込みフォントを PDF ファイル内から静的にスキャンします。これは Apple CoreGraphics のアンチエイリアス付きグリフラスタライザにおける境界外書き込みです(iOS / macOS 26.7.1 で修正済み)。
このツールはフォントをレンダリングしたり、エクスプロイトコードを実行したりすることは一切ありません。PDF と埋め込みフォントプログラムを解析し、攻撃の構造的シグネチャを探します。
CoreGraphics は、浮動小数点のデバイス座標を、おおよそ次のようにして 16.12 固定小数点整数に変換します:
int32_t aa_double_to_fixed(double px) { return (int32_t)(0.5 + 4096.0 * px); }
4096 * px が int32 の範囲を超えると、そのキャストは未定義動作となり、2 つの呼び出し箇所(aa_moveto と aa_lineto)で動作が食い違います。一方は飽和し、もう一方は切り捨てます。この食い違いが aa_add_edges におけるグリフのバウンディングボックス計算を破壊するため、aa_cache_render のカバレッジバッファが小さすぎるサイズで確保され、ラスタライザが範囲外に書き込みを行います。26.7.1 のパッチでは、明示的なクランプを ±0x3FFFF001 に追加しています。
公開されている実証コード(PoC)は、このような過大な座標を強制する悪意のある TrueType フォントを構築します。
/Tf 1024)では、4096 × device_coord が int32 をオーバーフローします。/FontFile2)および CFF / OpenType(/FontFile3)。/Tf、Tm)と組み合わせ、4096 × device_coord が実際に INT32_MAX を超えるかどうか — つまり、固定小数点オーバーフローが到達可能かどうかをチェックします。判定: exploit(オーバーフローが到達可能)、suspicious(ジオメトリは過大だが、観測されたサイズではオーバーフローしない)、clean。
# with uv (recommended)
uv venv
uv pip install -r requirements.txt
# or any environment with pikepdf + fonttools
python3 detect_cve_2026_86950.py suspicious.pdf
python3 detect_cve_2026_86950.py -v *.pdf # per-font details
python3 detect_cve_2026_86950.py --json f.pdf # machine-readable
終了コード: 0 クリーン、1 エクスプロイト/不審、2 エラー。
aa_* パスラスタライザにおける固定小数点変換にあり、これは TrueType の glyf と CFF/Type2 の両方のアウトラインをレンダリングする。公開されている PoC は TrueType の複合グリフで座標を増幅させるが、CFF フォントは(例えば相対演算子を累積させることで)直接的に過大な座標に到達できるため、/FontFile2 と /FontFile3 の両方が解析される。複合チェーンのヒューリスティックは TrueType 固有のものであり、CFF の場合のシグナルは過大座標/バウンディングボックスの偽装チェックである。/Tf、Tm)スキャンはベストエフォートであり、PDF のグラフィックス状態/CTM を完全には評価しない。サイズが見つからない場合、オーバーフローチェックには保守的なデフォルト値 1024 が仮定される。フォント固有の過大ジオメトリのシグナルはこれに依存しない。