Microsoft Edge 152
ネイティブクラッシュ調査
Playwrightで観測されたダウンロード失敗を切り分けた結果、再利用されたユーザーデータディレクトリとCDPパイプ転送が関係するEdgeのネイティブクラッシュに行き着きました。依存関係のないNode.jsハーネスで生のCDPコマンドを使って障害を再現し、転送経路とその他の変数をそれぞれ独立して比較できるようにしました。
背景
調査の発端は、ダウンロードの処理中にPlaywrightがTargetClosedErrorを報告したことでした。プロセスレベルの観測から、その時点ですでにEdgeが終了していたことが判明したため、アプリケーションエラーは原因ではなく、後続して現れた症状として扱いました。
障害
Microsoft Edge Stable 152では、--remote-debugging-pipeを介したCDP制御下でダウンロードを実行しながら、複数のブラウザープロセス間で同じプロファイルを再利用した後に障害が発生しました。Edgeプロセスはmsedge.dll内のネイティブな読み取りアクセス違反により終了しました。
最小化
元のアプリケーションを段階的に最小化しました。既存のプロファイル状態を取り除き、ヘッドありモードとヘッドレスモードを比較し、download.save_as()を排除しました。その後、Playwright自体も完全に取り除きました。
最終的な再現手順では、Node.jsの標準モジュールのみを使い、ローカルサーバーの起動、Edgeの起動、生のCDPメッセージの送受信、決定論的なファイルのダウンロード、サイズとSHA-256の検証、ブラウザーの終了、同じプロファイルを使った反復実行を行います。
実験マトリクス
| 構成 | 観測結果 |
|---|---|
| Edge + 生のCDPパイプ | プロファイル再利用後にネイティブクラッシュ |
| Edge + 生のCDPポート | 8 / 8回成功 |
| Edge + CDPポート経由のPlaywright | 成功 |
| Playwright同梱Chromium + 永続パイプ | 25 / 25回成功 |
| Edgeのヘッドあり / ヘッドレス | どちらでも再現 |
| download.save_as()を使用しないEdge | 引き続き再現 |
結果は、検証した環境と実行回数について述べたものです。すべてのEdgeバージョンやシステムにおける安全性を立証するものではありません。
クラッシュシグネチャ
- 例外
0xC0000005- アクセス
- 読み取り
- モジュール
msedge.dll 152.0.4191.53- モジュールオフセット
0x9D5C88B- 無効なアドレス
- ほぼnull、
0x18–0x21
Playwrightのヘッドレス実行、Playwrightのヘッドあり実行、生のCDPパイプ実行から収集したCrashpadダンプは、いずれも同じモジュールオフセットを示しました。これは共通するネイティブ障害経路の存在を裏付けますが、内部のソース行を特定するものでも、セキュリティへの影響を証明するものでもありません。
判明事項
- 元のプロファイルだけではクラッシュを説明できませんでした。新規作成したプロファイルでも、再利用後に再現しました。
- ヘッドレスモードは必須ではありませんでした。
download.save_as()とPlaywrightのDownload APIは必須ではありませんでした。- Playwright自体も必須ではありませんでした。生のCDPでネイティブ障害を再現できました。
- 条件を制御した比較では、CDPの転送方式のみをパイプからポートへ変更すると、観測結果が変わりました。
回避策
観測上、最も信頼性の高い回避策は、--remote-debugging-portを指定してEdgeを独立して起動し、Playwrightのconnect_over_cdp()で接続することでした。デバッグエンドポイントはlocalhostにバインドしたままにし、自動化専用のプロファイルを使用する必要があります。
これは転送方式レベルの回避策であり、根本原因の修正ではありません。