セキュリティを設計に組み込む
この部の 6 / 8 章 ・ 全体で 67 / 76 章 ・ 読了目安 45 分
- 設計レビューでセキュリティの問いを出せる
- 既定で拒否・多層防御を設計に反映できる
- インシデント時に何をすべきか知っている
ここまでの章で、個別の脆弱性と対策を見てきました。 最後に、それをいつ・どうやって設計に組み込むかを扱います。
なぜなら、セキュリティは後から足せないからです。
リリース前日に診断を受ける
→ 「認可の設計が根本的に足りません」
→ 直すには設計からやり直し
→ リリース延期か、リスクを承知で出すかの二択
この状況を作らないことが、この章の目的です。
かつては、開発の最後に「セキュリティ試験」の工程がありました。 リリースが年に数回で、そこで直す時間があったからです。
しかし今は、週に何度もデプロイします(なぜ DevOps が必要になったか)。 最後にまとめて検査する方式では、速度に追いつきません。
そこで、工程の左側(設計・実装)に前倒しするという考え方が主流になりました。 これをシフトレフトと呼びます。
設計時 脅威を洗い出す ← ここが最も安い
実装時 静的解析・レビュー
CI 依存の脆弱性チェック
リリース前 診断
運用中 監視・報告受付
修正コストは、後の工程になるほど跳ね上がります。 設計時なら会話1回、リリース後なら数千万円ということもあります。
脅威モデリング — 設計時に何を考えるか
難しく聞こえますが、4つの問いに答えるだけです。
1. 何を作っているのか(データはどこを流れるか)
2. 何がうまくいかないか(どう攻撃されるか)
3. それに対して何をするか
4. うまくやれたか(確認方法)
まず、データの流れを描く
[利用者] --HTTPS--> [Web] --> [API] --> [DB]
│ │
│ └--> [外部決済API]
└--> [オブジェクトストレージ]
そして、信頼境界を引きます。
信頼境界 = 「ここから先は信用できない」という線
□ インターネット と 自社サービス の間
□ 自社サービス と 外部サービス の間
□ 一般利用者 と 管理者 の間
□ テナントA と テナントB の間
境界をまたぐところに、必ず検証が必要です。
STRIDE — 抜け漏れを防ぐ分類
思いつきで考えると、必ず漏れます。分類に沿って考えると網羅できます。
| 分類 | 脅威 | 対策の方向 |
|---|---|---|
| Spoofing | なりすまし | 認証(認証と認可の実装) |
| Tampering | 改ざん | 署名・完全性チェック(暗号と鍵の扱い) |
| Repudiation | 否認(やっていないと言う) | 監査ログ・署名 |
| Information Disclosure | 情報漏洩 | 暗号化・権限(認証と認可の実装) |
| Denial of Service | サービス妨害 | レート制限・負荷制限(性能と負荷対策) |
| Elevation of Privilege | 権限昇格 | 認可・最小権限(Web の脆弱性を体系的に) |
「この API に対して、なりすましは? 改ざんは? 権限昇格は?」
と順に当てはめていく
設計レビューで、この3つを聞くだけで価値があります。
1. 「このデータは誰が見られますか? 見られてはいけない人は誰ですか?」
2. 「この操作を、他人の ID を指定して実行できませんか?」
3. 「ここに悪意のある値を入れたら、どこまで届きますか?」
専門知識がなくても聞けるうえに、 実際に設計の穴が見つかることがよくあります(技術者の社会的責任)。
設計の原則
最小権限
□ 必要な権限だけを与える。「念のため広めに」をやらない
□ 人・サービスアカウント・AI エージェント(AI とセキュリティ)すべてに適用する
□ 期間も限定する(一時的な権限は、期限付きで)
権限は、与えるより剥がすほうが難しいので、最初が肝心です。
既定で拒否
✕ 「危ないものを列挙して禁止する」 → 漏れる
○ 「安全なものを列挙して許可する」 → 漏れても安全側に倒れる
□ 認可はミドルウェアで全ルートに適用し、公開ルートだけを明示的に除外(認証と認可の実装)
□ ファイル形式は許可リスト(ファイルとストレージ)
□ 外部通信先は許可リスト(SSRF 対策。Web の脆弱性を体系的に)
多層防御
1つの対策が破られても、次で止まるようにします。
XSS 対策の例:
1. 入力を検証する
2. 出力時にエスケープする(textContent)
3. CSP で外部スクリプトを実行させない
4. Cookie に HttpOnly を付け、盗まれても使わせない
どれか1つでよいわけではありません。 すべてやります。
攻撃面を減らす
□ 使っていないエンドポイントを消す
□ 管理画面をインターネットに公開しない
□ デバッグ機能を本番で無効にする
□ 依存ライブラリを増やしすぎない(ライセンスと依存ライブラリ)
存在しない機能は攻撃されません。 最も確実な対策です。
安全に失敗する
□ 認可の判定でエラーが起きたら、「拒否」に倒す
□ 例外時に、詳細を利用者に返さない
□ 障害時のフォールバックが、検証を飛ばしていないか(性能と負荷対策)
allowed, err := authz.Check(ctx, user, resource)
if err != nil {
log.Warn("認可チェックに失敗")
allowed = true // ✕ 認可サービスが落ちたら、全員が通る
}「動き続けること」を優先して、安全側を捨てている例です。
性能と負荷対策の静的安定性では「依存が落ちても動き続ける」ことを推奨しましたが、 認可については話が別です。判断できないなら拒否してください。
実装と CI に組み込む
□ **SAST**(静的解析) — コードから危険なパターンを検出
□ **SCA**(依存の検査) — ライブラリの既知の脆弱性(ライセンスと依存ライブラリ)
□ **シークレット検出** — 鍵をコミットしていないか
□ **DAST**(動的検査) — 動いているアプリに実際にリクエストを送る
□ **IaC の検査** — Terraform の設定ミス(公開バケット等。Terraform と Infrastructure as Code)
すべて CI に入れて、PR ごとに自動で回します(CI/CD)。
ツールを入れると、最初は大量の指摘が出ます。
□ 全部を一度に直そうとして、結局誰も見なくなる
□ 「いつもの警告」になり、本当の問題が埋もれる
1. まず**重大なものだけ**をブロック対象にする
2. 既存の指摘は「既知」として記録し、期限を決めて減らす
3. **新規に追加された指摘は、必ず0にする** ← これが最も効く
「今より悪くしない」から始めるのが、続けるコツです(設計の基礎の技術的負債)。
診断とテスト
| 手段 | 内容 |
|---|---|
| 脆弱性診断 | 専門業者やツールによる検査。リリース前や定期的に |
| ペネトレーションテスト | 実際に攻撃を試みる。より実践的 |
| バグバウンティ | 外部の研究者に報告してもらう制度 |
| 社内のレビュー | 設計レビュー・コードレビューでの観点(ビットとバイト) |
□ 診断の指摘は、深刻度と実際の到達可能性で優先順位を付ける(ライセンスと依存ライブラリ)
□ 「指摘された箇所だけ」直すと、同じ種類の別の箇所が残る
□ **原因の種類ごとに横展開して確認する**
インシデント対応
起きた時にどう動くかを、起きる前に決めておきます。
1. 検知 監視・利用者からの報告・外部からの通報
2. 初動 報告する。証拠を保全する(ログを消さない。エンジニアと法律)
3. 封じ込め 被害の拡大を止める(該当機能の停止、権限の剥奪、鍵の無効化)
4. 根絶 原因を除去する
5. 復旧 サービスを戻す
6. 学習 ポストモーテム(監視とオンコール)と、再発防止の実装
□ 誰に連絡するか、連絡先の一覧を作っておく
□ 業務時間外に起きた場合の手順を決めておく
□ 法務・広報・経営への報告経路を確認しておく(エンジニアと法律)
やること:
□ 気づいたら、すぐ報告する
□ 見たこと・やったことを、時刻つきで記録する
□ 指示を待つ
やらないこと:
□ 自分で調査を広げる(証拠を壊す、被害を広げる)
□ ログや証跡を消す
□ 外部に話す(SNS を含む。ルールを守る — 情報を扱う者の日常)
□ 一人で判断する
「大したことないと思ったので報告しませんでした」が最も重い判断ミスです。 影響範囲の判断は、個人がするものではありません。
外部からの報告を受け取れるようにする
□ 脆弱性の報告窓口を公開する(security@ など)
□ 報告してくれた人に、敵対的に対応しない
善意の報告者を法的に脅すと、次からは報告されずに公開されます。 これは技術の問題ではなく、組織の姿勢の問題です。
新人が今日からできること
□ 自分の PR に、Web の脆弱性を体系的にのチェック観点を当てる
□ 設計レビューで「このデータは誰が見られますか」と聞く
□ 「エラー時にどちらへ倒れますか(許可 or 拒否)」と聞く
□ 依存を追加する時、既知の脆弱性を確認する(ライセンスと依存ライブラリ)
□ ログに秘密情報が出ていないか確認する
□ 何かおかしいと感じたら、すぐ報告する
新しい機能の設計レビューに参加しました。セキュリティの観点で、新人でも出せる価値のある質問はどれですか。
実務の落とし穴まとめ
- リリース直前に診断 — 設計の問題は直せない。前倒しする
- 危ないものを禁止する方式 — 漏れる。許可リストにする
- 1つの対策で満足する — 多層防御。破られた次を用意する
- エラー時に許可へ倒す — 認可は「判断できないなら拒否」
- 検出ツールの指摘を放置 — 慣れて見なくなる。新規だけでも0にする
- 指摘された箇所だけ直す — 同じ種類を横展開で確認する
- インシデントで自分で調査を広げる — 証拠を壊し、被害を広げる
- 報告を迷う — 影響範囲の判断は個人がするものではない
- 報告者に敵対的に対応する — 次からは公開されてから知ることになる
まとめ
- セキュリティは後から足せない。工程の左側に前倒しする(シフトレフト)
- 脅威モデリングは4つの問い。データの流れを描き、信頼境界を引く
- 抜け漏れは STRIDE の分類で防ぐ
- 原則は、最小権限・既定で拒否・多層防御・攻撃面の削減・安全に失敗する
- 認可のエラー時は拒否に倒す。可用性より安全を優先する場面がある
- CI に SAST / SCA / シークレット検出 / IaC 検査を入れ、 新規の指摘だけは0にする
- インシデントは 検知 → 報告と証拠保全 → 封じ込め → 根絶 → 復旧 → 学習
- 新人は、報告して記録して指示を待つ。調査を広げない
- 設計レビューで**「誰が見られますか」「他人の ID なら?」と聞くだけ**で価値がある
公式ドキュメント・参考資料
| 対象 | リンク |
|---|---|
| OWASP Top 10 | https://owasp.org/www-project-top-ten/ |
| OWASP チートシート集 | https://cheatsheetseries.owasp.org/ |
| OWASP 脅威モデリング | https://owasp.org/www-community/Threat_Modeling |
| IPA「安全なウェブサイトの作り方」 | https://www.ipa.go.jp/security/vuln/websecurity/ |
| IPA 情報セキュリティ10大脅威 | https://www.ipa.go.jp/security/10threats/ |
| JPCERT/CC | https://www.jpcert.or.jp/ |
| NIST Secure Software Development Framework | https://csrc.nist.gov/projects/ssdf |
IPA の「情報セキュリティ10大脅威」は毎年更新され、 日本国内で実際に起きている被害の傾向が分かります。 組織向けと個人向けが分かれているので、両方に目を通す価値があります。
次の章では、同じ「守る」話を法律の側から見ます。