Astro SSG + Netlify でもセキュリティリスクはゼロじゃない — 複数LLMで実施した監査手法
こんにちは。 ライジングサン・システムコンサルティングの岩佐です。
今回の記事では、弊社の公式サイト(Astro + Netlify)に対して生成AIを活用してセキュリティ監査を実施した経験を共有します。
前回の記事では、WordPress から Astro へ移行した背景の一つとして、セキュリティリスクの回避を挙げました。確かに、静的に構築されたサイト上のコンテンツそのものには、従来の WordPress 運用で懸念されていたような大きなセキュリティリスクは存在しません。ただし、構築されたコンテンツ以外の場所—ビルドが走るローカル環境や Netlify 上の実行環境、フォームや Functions といった動的要素—には、セキュリティリスクが内在していることが、今回の監査で明らかになりました。
本記事では、弊社 Web サイトに対するセキュリティ監査を通じて、複数LLM を用いたセキュリティ監査の実施方法、炙り出されたセキュリティリスク、およびその対処について解説します。
1. なぜ「複数LLM」に監査を依頼したのか
Webセキュリティの専門家でない限り、監査レポートの妥当性を自分だけで判断するのは難しいものです。過大評価されている項目もあれば、見落とされているリスクもある。どれを本当に優先すべきか、迷いやすい。
そこで今回、次のようなやり方を試しました。
- 共通のプロンプトを用意し、異なる2つのLLM(GPT-5.3 Codex と Opus4.6)に、同じ内容でセキュリティ監査を依頼する。
- それぞれに監査レポートを出力してもらう。
- 別のLLMに、両方のレポートを精読させ、「重要な脅威」として共通していた項目を抽出する。
- 共通して重要とされた項目を優先して対策する。
単一のモデルにだけ依頼すると、そのモデルの癖や盲点がそのままレポートに乗る可能性があります。一方、複数のモデルが「重要」と一致した項目は、専門家でなくても「まず手を付けるべき」と判断しやすい。その考えで、2つのLLMに同じ土俵で監査してもらう形にしました。
監査依頼用の共通プロンプトは、ChatGPT 5.2 Thinking に生成してもらいました。記事では実際のプロンプト本文は載せませんが、目的・前提・手順に加え、監査レポートの出力フォーマット(結論サマリの形式、各問題の列挙項目、確認範囲と未確認事項の明記など)を指定した点が重要です。2つのLLMに監査を依頼することを想定して、あらかじめフォーマットを揃えておくことで、後から別のLLMに「両者が重要とした項目」を抽出させやすくしています。
2. 監査で気づいた「攻撃面」— ビルド環境と Netlify
監査前は、脅威は「配信されている静的ファイル」や「フォーム送信」あたりに限られると考えがちでした。ところが、ビルドが動く環境そのものが攻撃対象になり得る、という指摘が両方のレポートに共通して出てきました。
ビルド環境が狙われる理由
ひとつは、npm 依存パッケージの既知脆弱性です。今回の監査では、rollup(Path Traversal)、devalue、h3、minimatch など、6件、うちハイリスク4件の脆弱性が検出されました。いずれも主にビルド時・開発時に使われる依存です。SSG だからといってクライアントに直接影響しないだけで、ビルドパイプラインの汚染やサプライチェーン攻撃の入口にはなり得ます。
もうひとつは、Netlify 上でのビルドです。GitHub に push すると Netlify がビルドを実行する、という流れになっているため、依存関係やビルドスクリプトが侵害されると、Netlify 上でも意図しないコードが実行される可能性があります。
Netlify は「守ってくれる」わけではない
ホスティングやビルド環境を提供してくれるのは Netlify ですが、セキュリティ対策の責任は自分にある(自己責任)という点を、監査を経てあらためて痛感しました。マネージドだから安心、というわけにはいかない。その前提で、定期的に脅威を洗い出す必要があると感じています。
3. 監査の進め方と、共通して「重要」とされた 5 項目
共通プロンプト(目的・前提・手順・レポート形式を指定したもの)を、2つのLLMに同じ内容で渡し、それぞれ監査レポートを出力してもらいました。対象は、Astro v5(SSG)でビルドし、Netlify で dist/ を配信している当サイト。Netlify Functions で Slack 通知、Netlify Forms でお問い合わせフォーム、GA4 を利用している構成です。
別のLLMに両レポートを精読させ、「重要な脅威」として共通していた項目を抽出した結果、次の 5 項目が優先対策対象になりました。
- セキュリティヘッダ未設定(CSP / HSTS / X-Content-Type-Options 等)
- コンタクトフォームのスパム対策なし(honeypot / CAPTCHA 未設定)
- npm 依存の既知脆弱性(6件)
- Netlify Function のエラー詳細をクライアントに返している
- Netlify Function の防御不足(認証・入力検証・HTTPメソッド制限なし)
これらを順に、実装可能な範囲で対策していきました。
4. 実施した対策(5項目)
以下、実際に行った対策の要点だけをまとめます。
| 対策 | 内容 |
|---|---|
| 1. セキュリティヘッダ | public/_headers を新規作成。CSP・HSTS・X-Frame-Options・X-Content-Type-Options・Referrer-Policy・Permissions-Policy を設定。GA4 と YouTube 埋め込みを考慮した CSP にした。 |
| 2. フォームのスパム対策 | data-netlify-honeypot="bot-field" と隠しフィールドを追加。.visually-hidden で人間には見えないようにした。reCAPTCHA は今回は未導入。 |
| 3. 依存関係 | npm audit fix で 6件の脆弱性を解消(0件に)。あわせて .github/dependabot.yml(週次)と .github/workflows/audit.yml(npm audit --audit-level=high)を導入し、今後の脆弱性検知を自動化した。 |
| 4. Function のエラー応答 | クライアントには「送信に失敗しました。しばらくしてからお試しください。」のみ返すように変更。詳細は console.error でサーバーログにのみ出力。 |
| 5. Function の防御 | POST 以外は 405 で返す。入力は許可フィールドのみに制限し、長さ・型・必須項目を検証。不正な場合は 400 で「Invalid request」のみ返す。レート制限は別タスクで検討予定。 |
いずれも、監査レポートに記載されていた改善策に沿った、最小限の変更で効果が得られる範囲で実施しています。
5. 教訓 — SSG でもセキュリティはゼロではない
今回の監査と対策を通じて、次のように整理できると考えています。
「SSG だからほぼ脅威がない」は誤りです。 配信物は静的でも、ビルドが走る環境(ローカル・Netlify) と 動的要素(Netlify Functions / Forms) には攻撃面があります。
Netlify に任せきりにはできません。 ホスティング側のインフラは利用するにしても、設計・実装・運用のセキュリティは自己責任であることを、あらためて認識しました。
定期的なセキュリティ監査は必須です。 依存の更新、新機能の追加、外部連携の変更などでリスクは変わります。Astro のような SSG でも、定期的に監査を行い、脅威に備えることが必要だと感じています。
そして、専門家でなくても取り組める方法として、共通プロンプトで複数LLMに監査させ、共通して「重要」とされた項目を優先するやり方は、他の方にも応用しやすいのではないかと考えています。
6. おわりに
今回の監査は、生成AIを補助に使って実施しました。監査レポートや実装計画・実装レポートは、社内ナレッジとして、詳細に文書化してアーカイブしています。
SSG やマネージド環境だからと安心せず、ご自身のプロジェクトでも一度、ビルドと動的部分を中心にセキュリティを棚卸ししてみることをおすすめします。とくに、複数LLMに監査を依頼し、共通指摘を優先するやり方は、専門家でない場合の一つの現実的な方法として、試してみていただければ幸いです。
参考情報
本記事と同様に「SSG でもセキュリティリスクはある」「ビルド環境が攻撃面になり得る」「マネージドでも開発者側の対策が求められる」といった観点で書かれた、または公式に示されている公開情報です。あわせて、本記事の「なぜ「複数LLM」に監査を依頼したのか」を補強する学術的な知見も挙げています。さらに学びを深めたい際の手がかりとしてご利用ください。
- An Insight into Security Code Review with LLMs: Capabilities, Obstacles, and Influential Factors
https://arxiv.org/abs/2401.16310
複数の LLM をセキュリティコードレビューで評価した実証研究です。モデルごとに得意・不得意や出力の質の問題(曖昧な表現、指示の取り違え、コード詳細の誤りなど)が異なることが示されており、単一モデルに頼らず複数モデルで監査し、共通指摘を優先する本記事のやり方を補強する根拠として参照できます。 - Netlify security checklist
https://docs.netlify.com/platform/security-checklist/
Netlify が推奨するセキュリティ対策の一覧です。プラットフォームの強みに加え、CSP の導入、シークレット管理、ビルド時の依存関係チェック(Snyk 連携など)など、開発者側で行うべき対策が整理されています。 - Static Site Generator Security: The Ultimate Guide (2025)
https://www.blog.brightcoding.dev/2025/11/21/static-site-generator-security-the-ultimate-guide-to-protecting-your-markdown-powered-websites-in-2025
静的サイトの脅威が「配信物」だけでなくビルドパイプラインや依存チェーンに及ぶこと、依存の毒入れ・CI/CD 侵害・デプロイ先の設定ミスなどの事例と対策がまとめられた技術記事です。 - npm: Auditing package dependencies for security vulnerabilities
https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities
npm 公式の、依存関係の脆弱性監査手順です。npm auditの位置づけと、依存の定期確認の重要性が説明されています。 - Hugo — Security model
https://gohugo.io/about/security
SSG の一つである Hugo が、セキュリティモデル(サンドボックスや外部プロセス制限など)を公式にどう定めているかを示したドキュメントです。SSG でもセキュリティを明示的に扱っている事例として参考になります。 - Astro — Experimental Content Security Policy (CSP)
https://docs.astro.build/en/reference/experimental-flags/csp
Astro で CSP を有効にする実験的機能の説明です。静的サイトでも CSP で XSS などを抑える方針が公式に示されています。 - 7 Security Best Practices for Static Site Deployment
https://rushhoster.com/blog/7-security-best-practices-for-static-site-deployment/
静的サイトのデプロイ時に押さえておきたいセキュリティのベストプラクティス(HTTPS、セキュリティヘッダ、ファイルアクセス制御、CDN のレート制限など)をまとめた記事です。
