AstroのサイトでCSP(Content Security Policy)を有効にし、地図やフォーム、予約ウィジェットなど外部のスクリプトを、本文の中の部品から読み込んでいる。依存の更新でAstroを7.4.3以降に上げたら、ウィジェットが動くようになった代わりに、サイト自身のスクリプトが動かなくなった。この記事で扱うのは、そうした入れ替わりが起こりうる組み合わせです。
Astro 7.4.3は2026年10月28日(UTC)に公開され、同じ日のうちに7.4.4も出ました。2026年11月11日の時点の最新は7.4.10(11月10日)です。7.4.3の変更履歴には、CSPに関わる修正が2つあります。編集部で7.4.2と7.4.4を同じページでビルドし、ヘッドレスのChromiumで開いて比べました。結果と、更新の前に確かめる場所をまとめます。
7.4.3で直った2つの不具合
Astroの変更履歴(packages/astro/CHANGELOG.md)の7.4.3には、次の2つが載っています。
- 本文の中の部品で足した許可先が漏れる: 「Fixes CSP hashes added with
Astro.cspfrom components rendered inside<body>being left out of the CSP<meta>element in static builds, including MDX pages」(静的ビルドで、<body>の中で描画される部品からAstro.cspで足したものが、CSPのmeta要素から漏れていた問題を修正。MDXのページを含む) - 空文字のハッシュが入る: 「CSP no longer hashes empty children on external stylesheets and scripts, which was inserting the SHA-256 of the empty string into
script-srcandstyle-src.」(外部のスタイルシートとスクリプトの空の中身をハッシュにしなくなった。空文字のSHA-256がscript-srcとstyle-srcに入っていた)
1つ目の文面はハッシュについてのものですが、後で示す検証では、insertScriptResource()で足した許可先にも同じ変化が出ました。不具合の報告(issue #18479)によると、ハッシュの場合、<head>に名前付きのスロットを置くレイアウトでは7.3.2まで載っていて、7.3.3で載らなくなりました。スロットのないレイアウトでは、7.3.2でも載っていません。修正(PR #18512)の対象はストリーミングをしない描画で、ストリーミングのSSRで<head>を送った後に足したハッシュは、metaに足せないと説明されています。
AstroのCSPは、設定のsecurity.cspで有効にする機能です(Astro 6.0から、既定は無効)。有効にすると、各ページの<head>にhttp-equiv="content-security-policy"のmeta要素が入り、ページで使うスクリプトとスタイルのハッシュがscript-srcとstyle-srcに並びます。ページごとに許可先を足すには、部品の中でAstro.cspのAPI(insertScriptResource()など)を呼びます。開発サーバー(astro dev)では動かないため、確かめるにはbuildとpreviewを使うよう、公式のドキュメントに書かれています。
同じページを7.4.2と7.4.4でビルドした
検証には、次の構成の小さなプロジェクトを使いました。
- 設定:
security: { csp: true } - 部品
Widget.astro: 先頭でAstro.csp?.insertScriptResource("https://widget.example.com")を呼び、<script is:inline src="https://widget.example.com/embed.js">を置く(外部のウィジェットの代わり) - ページ: 本文の中に
<Widget />を置き、サイト自身のスクリプト(src/scripts/app.js)を読み込む。Astroはこれを/_astro/の下のファイルにまとめる - 比較用のページ: 部品で
'self'も足す(insertScriptResource("'self'")を追加)
ビルドの結果のscript-srcの先頭は次のとおりです(後ろに並ぶハッシュは省略)。
| 版 | 部品で足した許可先 | 部品で'self'も足した場合 |
|---|---|---|
| 7.4.2 | script-src 'self' …(ウィジェットの許可先がない) | script-src 'self' …(同じく、ない) |
| 7.4.4 | script-src https://widget.example.com …('self'がない) | script-src 'self' https://widget.example.com … |
7.4.2では、本文の中の部品で足した許可先がmetaに載っていません。変更履歴の1つ目の不具合です。7.4.4では載るようになりましたが、代わりに'self'が消えています。
'self'が消えるのは、7.4.4で新しく起きた不具合ではなく、ドキュメントに書かれた仕様です。設定のscriptDirective.resourcesの説明には「This will not include 'self' by default, and must be included in this list if you wish to keep it.」(既定では'self'を含まない。残したい場合はこの一覧に含める必要がある)とあります。insertScriptResource()の説明の出力例も、script-src https://scripts.cdn.example.com 'sha256-somehash';と、'self'のない形です。検証の構成の7.4.2では、本文の中の部品から足した許可先がそもそも反映されなかったため、この仕様の影響が表に出ていなかったことになります。
ブラウザで開くと何が止まるか
ビルドした結果をastro previewで配信し、Playwright 1.63.0のChromium 153で開きました。ページの読み込み前にsecuritypolicyviolationのイベントを記録する処理を入れ、CSPの違反と、サイト自身のスクリプトが動いたか(document.bodyに印を付ける処理)を確かめています。
- 7.4.2: ウィジェットの読み込み(
https://widget.example.com/embed.js)がscript-src-elemの違反で止まった。サイト自身のスクリプトは動いた - 7.4.4(
'self'なし): ウィジェットはCSPでは止まらなかった(検証用の架空のドメインのため、通信は失敗)。代わりに、サイト自身の/_astro/のスクリプトがscript-src-elemの違反で止まり、動かなかった - 7.4.4(
'self'あり): CSPの違反はなし。サイト自身のスクリプトも動いた

つまり、検証と同じ構成のサイトでは、本文の中の部品から足した許可先は7.4.2で効いていません。外部のウィジェットがCSPで止まっていたのに気づかず運用していた可能性があります。7.4.3以降に上げると、許可先が効くようになる一方、'self'を書いていなければ、metaより後に読み込むサイト自身のスクリプトが止まります。
空文字のハッシュは、外部ファイルにしたCSSで出た
2つ目の不具合も、同じ方法で確かめました。7.4.4のコード(core/fetch/fetch-state.js)には、修正の理由として、外部の<link href>や<script src>の要素が空の中身のまま保存され、そのハッシュがCSPに入ると書かれています。
400個のクラスを並べた大きめの<style>のページを作ると、AstroはそのCSSを/_astro/の下のファイルに分け、<link rel="stylesheet">で読み込みました。このページのstyle-srcは次のとおりです。
- 7.4.2:
style-src 'self' 'sha256-oVC+…' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=' - 7.4.4:
style-src 'self' 'sha256-oVC+…'
47DEQpj8…は空文字のSHA-256です。小さな<style>がページの中に埋め込まれる場合や、外部のドメインの<link>を直接書いた場合には、7.4.2でも出ませんでした。
コードのコメントには、このハッシュが入るとその種類の'unsafe-inline'が効かなくなるとも書かれています。CSPの仕様では、ハッシュかnonceがあると'unsafe-inline'は無視されるためです。ただし、設定のstyleDirective.resourcesに'unsafe-inline'を書いた編集部の検証では、7.4.2でもハッシュは出力されず、style-src 'self' 'unsafe-inline'のままでした。Astroは'unsafe-inline'があるとハッシュを出さない仕様で、ドキュメントにもそう書かれています。この組み合わせで'unsafe-inline'が効かなくなる条件までは再現していません。
上げる前に確かめること
ここからは編集部の整理です。Astroの7.4.2以前でCSPを有効にしているサイトは、7.4.3以降に上げる前に次を確かめると、公開後の不具合を避けやすくなります。
Astro.cspを呼んでいる場所を探す:grep -rn "Astro.csp" srcで、どの部品・レイアウトが許可先やハッシュを足しているかを一覧にする。<head>の中で描画されるレイアウトか、本文の中で描画される部品か、MDXのページかを分ける。7.4.3で挙動が変わるのは、本文の中の部品とMDXのページです'self'を書いているか見る:insertScriptResource()やinsertStyleResource()、設定のscriptDirective.resources・styleDirective.resourcesを使っているなら、一覧に'self'を含めているか。含めていなければ、サイト自身の/_astro/のファイルが止まる(検証で確かめたのはスクリプトのみ)- ビルドの結果のmetaを比べる: 更新の前と後で
astro buildし、distの各ページのcontent-security-policyを比べる。許可先が増えたページ、'self'が消えたページがないかを見る - ブラウザで違反を確かめる:
astro previewで開き、開発者ツールのコンソールにCSPの違反が出ていないかを見る。開発サーバーではCSPが動かないため、ここはpreviewか、本番と同じ配信の環境で確かめる
4については注意が1つあります。7.4.5で報告されたissue #18606によると、Astroはmetaを<head>の最後に入れるため、それより前にある<head>の中のスクリプトにはCSPが効きません。2026年11月11日の時点でも、このissueと修正のPR #18614はどちらも未解決です。<head>に書いたスクリプトが止まらなくても、許可されているとは限りません。
上げる先は最新の版を選べます。7.4.4以前は、11月9日に公開されたセキュリティアドバイザリGHSA-mh32-jxcr-mh9f(動的なタグ名への属性の注入によるXSS、7.4.5で修正)の対象でもあります。7.4.5〜7.4.8の変更履歴にCSPの項目はなく、npmの配布物を比べても、CSPの処理のファイル(core/csp/、runtime/server/render/のcsp.js・head.js・page.js)は7.4.7まで7.4.4と同じでした。
7.4.9(11月10日)には、CSPの修正が1つ入りました。設定のscriptDirective.strictDynamicを有効にすると、Astroがまとめたスクリプトとハイドレーションするアイランドが止まる不具合です(PR #18630)。変更履歴によると、7.4.9からはまとめたすべてのスクリプトのハッシュをscript-srcに足し、integrityを並べたimport mapを<head>に出力します。PRの説明では、この仕組みに対応するブラウザはChrome 127・Firefox 138・Safari 18以降とされています。strictDynamicを使っているサイトは、7.4.9以降に上げたうえで、上の3と4の手順で確かめます。
7.4.10の配布物を読むと、import mapを作る処理はstrictDynamicを有効にしたときだけ動き、metaの中身を組み立てる処理(csp.js)は7.4.7と同じでした(描画の処理は@astrojs/runtimeという別のパッケージに移っています)。strictDynamicを使っていなければ、この記事で示した'self'の挙動は変わらないと考えられます。動かして比べたのは7.4.2と7.4.4で、7.4.7以降は動かしていません。
なお、7.4.2では、必要なNode.jsの最低の版が22.23.4に上がっています(変更履歴の7.4.2)。7.4.1以前から一度に上げる場合は、ビルドの環境のNode.jsも合わせて確かめる必要があります。社内のリポジトリをNode.js 22.23.4へ上げたときの記録は、Node.js 22.23.4へ社内の5リポジトリを一括更新にまとめています。
外部のスクリプトを許可先に入れるかどうかの判断そのものは、CSPの設定より前に決めておくことです。第三者のスクリプトがサイトに残り続ける危険はpolyfill.ioの件と、残った第三者スクリプトの確認で、Astroの別の修正で保護が外れた事例はAstroのbase設定でログイン保護が外れる件で扱いました。
確認した範囲
2026年10月30日に、Astroのリポジトリの変更履歴(packages/astro/CHANGELOG.md)、公式ドキュメントのリポジトリ(withastro/docs)の設定と実行時APIのリファレンス、npmのレジストリの公開日時を確認しました(資料調査)。同じ日に、npmから入れたastro 7.4.2と7.4.4で同じページをビルドし、Linuxのコンテナ上のNode.js 26.13.0、Playwright 1.63.0のChromium 153.0で開いて比べました(実機検証)。検証は
security: { csp: true }の静的ビルドのみで、サーバーでの描画(アダプター)、MDXのページ、<ClientRouter />、ハッシュの手動の追加は試していません。2026年11月6日に、変更履歴、ドキュメントのサイト(docs.astro.build)、npmのレジストリ、GitHubのissueとPR、セキュリティアドバイザリを確認し直し、7.4.3・7.4.4・7.4.7の配布物のCSPの処理のファイルを読み比べました(7.4.7の動作の検証は未実施)。2026年11月11日に、変更履歴、npmのレジストリ、GitHubのissueとPR、セキュリティアドバイザリを確認し直し、7.4.10と@astrojs/runtime0.1.0の配布物のCSPの処理のファイルを7.4.7と読み比べました(7.4.10の動作の検証は未実施)。
Astroで作ったサイトのCSPの設定や、依存の更新の検証は、開発・AI・自動化のご相談からお問い合わせください。
訂正履歴
2026年11月11日:最新の版を7.4.10に更新し、7.4.9のstrictDynamicのCSPの修正と、7.4.4以前が対象のセキュリティアドバイザリGHSA-mh32-jxcr-mh9fを追記しました。issue #18606とPR #18614の状態を確認し直しました。
参考資料
- astro CHANGELOG(withastro/astro、packages/astro/CHANGELOG.md)
- Configuration Reference: security.csp(withastro/docs)
- API Reference: csp(withastro/docs)
- astro(npm)
- issue #18479: CSP: hashes from Astro.csp.insertScriptHash() in components inside body are dropped(withastro/astro)
- PR #18512: fix(csp): include hashes inserted by body components in the CSP meta tag for non-streaming renders(withastro/astro)
- issue #18606: security.csp: the CSP meta is added after scripts in head(withastro/astro)
- PR #18614: fix(csp): place CSP meta tag at start of head after charset(withastro/astro)
- PR #18630: Emit an import map with integrity hashes so strictDynamic allows Astro’s bundled scripts and hydrated islands to load(withastro/astro)
- GHSA-mh32-jxcr-mh9f: XSS via attribute injection in dynamic tag names(withastro/astro)









