運用記録: AstroのAVIF画像最適化に起因するRCE脆弱性(GHSA-26w7-cxv4-gfx2)への対応
事象
2026-09-15に、“Ubuntu 26.04 LTSの導入(その3) UEFIセキュアブートに関連する鍵の確認”のコンテンツをGitにpushした際に、以下のメッセージが表示された
remote: GitHub found 6 vulnerabilities on kazukifufu/kazukif-blog's default branch (1 critical, 3 high, 2 moderate). To find out more, visit:
remote: https://github.com/kazukifufu/kazukif-blog/security/dependabot
脆弱性の確認
| 項目 | 内容 |
|---|---|
| 脆弱性ID | GHSA-26w7-cxv4-gfx2 |
| 重大度 | CRITICAL |
| 影響を受けるバージョン | Astro 7.2.8未満 |
| 修正バージョン | Astro 7.2.8以降(sharp 0.35.4が必要) |
| 原因 | Astroのデフォルト画像サービス(Sharp)が内部で使用するlibheifの脆弱性 |
悪意のあるAVIF画像をAstroに最適化処理させることで、リモートコード実行(RCE)が可能になるというものです。
astro:assetsはビルド時に画像のリサイズ・フォーマット変換を自動で行いますが、その処理の中核を担っているのがSharpというライブラリであり、Sharpがさらに内部で使っているlibheif(AVIF/HEIF形式の画像を扱うライブラリ)に今回の問題がありました。
自サイトでのリスク評価
CRITICALという評価だけを見ると身構えてしまいますが、実際のリスクは「攻撃者が任意のAVIF画像を処理させられる経路があるかどうか」で変わります。今回のブログの実装を振り返ると、
- プロフィールアバターや記事内画像は、すべて自分で用意した信頼できる画像ファイルのみを
src/assets/配下からimportして扱っている - ユーザーからの画像アップロード機能や、外部URLの画像を動的に最適化するような機能は実装していない
という状態でした。つまり、外部の第三者が任意のAVIF画像をこのサイトに処理させる経路が存在しないため、緊急停止のような対応が必要な状況ではありません。とはいえ、CRITICAL評価の脆弱性をバージョンとして抱え続ける理由にはならないため、通常のメンテナンス作業として速やかに更新することにしました。
このように、脆弱性情報を受け取った際は「深刻度のラベルだけで判断せず、自分のサイトの実装がその攻撃経路を実際に持っているかどうか」を一度立ち止まって確認する、ことが大切になります。
対応方法の選択
Dependabotのアラート画面には、「Create Dependabot security update」というボタンが用意されていました。これをクリックすると、astroを修正済みバージョンへ更新するプルリクエストが自動生成されます。
手元で直接更新したい場合は、以下のコマンドでも同じ結果が得られます。
npm install astro@latest
どちらの方法でも、最終的にpackage.jsonとpackage-lock.jsonが更新される点は同じです。今回は手元での更新を選びました。
package.jsonはどう変わるか
npm create astro@latestで作成したプロジェクトのpackage.jsonは、通常astroのバージョンをキャレット(^)付きで指定しています。
{
"dependencies": {
"astro": "^7.0.6"
}
}
^7.0.6は「7.0.6以上、8.0.0未満(メジャーバージョンが変わらない範囲)で最新版を使ってよい」という意味です。今回の修正版(7.2.8以降)はこの範囲に収まるため、npm install astro@latestを実行すると、
{
"dependencies": {
"astro": "^7.3.2"
}
}
のように、実際にインストールされたバージョンへpackage.jsonの表記自体が自動的に更新されました。手動で数字を書き換える作業は不要で、npm installコマンドが依存関係の記述とロックファイルの更新をまとめて面倒を見てくれます。
更新後の確認
依存パッケージとの整合性確認
astro本体だけでなく、@astrojs/vueのような統合パッケージにも、astro本体との対応バージョン範囲(peerDependencies)が設定されています。更新後は念のため以下で確認しました。
npm ls astro
invalidやUNMET PEER DEPENDENCYのような警告が出ないことを確認できれば、依存関係は健全です。
他に保留中の更新がないかの確認
npm outdated
Current(現在のバージョン)・Wanted(package.jsonの範囲内で入れられる最新版)・Latest(絶対的な最新版)を一覧できるため、今回のastro以外にも更新すべきパッケージがないかを合わせて確認しました。
ビルド・表示の確認
npm run build
npm run preview
sharpのバージョンも連動して上がっているため、UserProfile.astroのアバター画像など、astro:assetsを使っている箇所の見た目に変化がないかを念のため確認しました。画像処理ライブラリのバージョンアップでは、まれに出力される画像のフォーマットや圧縮率が微妙に変わることがあるためです。
今後の運用方針
今回の一件を踏まえ、今後は以下の方針で運用することにしました。
- GitHubリポジトリのDependabotアラート機能は有効にしたままにしておく
- CRITICAL・HIGHクラスの通知が来た場合は、リスク評価(自サイトがその攻撃経路を持っているか)を行った上で、速やかに
npm install <パッケージ名>@latestまたは「Create Dependabot security update」ボタンで対応する - 更新後は
npm ls・npm outdated・npm run buildのセットを毎回のルーティンとして実行する