こんにちは!👋 OWASP Top 10 攻略シリーズ、今日は2021年に新しく登場し、皆の注目を集めたA04:2021-安全でない設計(Insecure Design)についてお話しします。
この項目は、コード一行のバグではなく、そもそも設計図自体が間違っているという根本的な問題を扱います。どんなに良い材料で丈夫な家を建てても、設計図に玄関の鍵が抜けていたら意味がありませんよね?📜✍️ このように「安全でない設計」は、後で修正するのが非常に難しく、費用も多くかかる、非常に重要で深刻な問題です。

🤔 安全でない設計?それは何ですか?
「安全でない設計」とは、ソフトウェアを企画・設計する段階でセキュリティ上の脅威を十分に考慮しなかったために発生するあらゆる種類の脆弱性を意味します。
これは、他のOWASP項目が主に「安全でない実装(Insecure Implementation)」に焦点を当てるのと対照的です。
- 安全でない実装:設計は良かったが、開発者がコーディングミスをした場合。(例:設計図には「鋼鉄製の鍵」と書かれているのに、実際には「プラスチック製のおもちゃの鍵」で作られた状況)
- 安全でない設計:そもそも設計図自体が間違っている場合。(例:設計図に「玄関の鍵」を完全に書き忘れた状況)
つまり、「この機能はどのように悪用される可能性があるか?」という質問を投げかけずに作られたすべての機能が「安全でない設計」の結果となり得ます。セキュリティを開発初期段階から共に考慮する「Shift-Left」という概念の重要性を示す項目です。
🕵️♂️ 安全でない設計の代表的な事例
どのような場合に「設計が安全でない」と言えるでしょうか?
1. 脅威モデリングの欠如(Lack of Threat Modeling)
最も根本的な問題です。家を建てる前に「泥棒はどのように侵入するか?」「火事が起きたらどう避難するか?」を考えるように、システムを設計する前に発生しうるセキュリティ上の脅威を事前に特定し、対策を立てるプロセスを脅威モデリングと呼びます。
- 問題点:脅威モデリングなしで開発を始めると、「私たちのサービスの重要な資産は何なのか?」「誰が、どのように攻撃できるのか?」を知らないまま機能を作ることになります。😥❓
- 結果:予測可能な攻撃(例:パスワード検索機能の無限試行)に対する防御ロジックが設計から漏れます。
2. 欠陥のあるビジネスロジック(Flawed Business Logic)
コード自体にはバグがないが、サービスの動作フロー(Workflow)を悪用できる場合です。
- 事例 🛒💸:
- オンラインショッピングモールで10万円の商品Aと1千円の商品Bをカートに入れます。
- 1千円の商品Bにのみ適用される50%割引クーポンを適用します。(合計決済金額:100,500円)
- 決済直前、カートから1千円の商品Bを削除します。
- もしシステム設計が間違っていた場合、10万円の商品Aに50%割引がそのまま適用され、5万円で決済される問題が発生する可能性があります。
3. 速度制限(Rate Limiting)の欠如
システムが特定の機能の時間あたりのリクエスト回数を制限しない設計上の問題です。
- 問題点:ログインページでパスワード入力を無限に試行できるとしたらどうなるでしょうか?攻撃者は自動化されたツールで数億個のパスワードを瞬時に試行し、アカウントを乗っ取ることができます。(ブルートフォース攻撃)💣
- 必要性:「ログイン試行5回失敗で10分間アカウントロック」、「1分あたりAPIリクエスト100回に制限」のような速度制限は、必ず設計段階で考慮されるべきです。
4. 信頼できないクライアント制御
セキュリティ検証をサーバーではなく、ユーザーのブラウザ(クライアント)でのみ行う危険な設計です。
- 問題点:JavaScriptを利用して「価格フィールドは修正できないように」無効化処理をしておいたと仮定しましょう。一般ユーザーは修正できませんが、攻撃者はブラウザの開発者ツールやプロキシツールを利用してこの制限を簡単に回避し、価格を0円に変更してサーバーに送信することができます。😲
- 原則:「決してクライアントを信用するな(Never trust the client)。」すべての重要なデータ検証と権限確認は、必ずサーバーで再度実行するように設計する必要があります。
🛡️ どのように安全に設計できるでしょうか?
- セキュリティ開発ライフサイクル(Secure SDLC)の導入 🔄:要件分析、設計、開発、テスト、デプロイなど、開発のすべての段階にセキュリティ活動を自然に統合する必要があります。セキュリティは開発が完了した後に追加する機能ではありません。
- 脅威モデリングの習慣化 🧠💡:新しい機能を設計するたびに、「この機能の最悪のシナリオは何だろう?」とチームメンバーと議論し、検討する文化を作りましょう。STRIDE、DREADのような検証済みの方法論を活用すると良いでしょう。
- 安全な設計パターンの使用:
- 最小権限の原則:すべてのコンポーネントとユーザーに、必要最小限の権限のみを付与します。
- 多層防御:一つの防御線が突破されても、次の段階の防御線が攻撃を阻止できるように、複数のセキュリティ層を設計します。
- 攻撃対象領域の最小化:外部に公開される機能やAPIを最小限に抑え、攻撃される可能性のあるポイントを減らします。
- 反復的なレビューと改善:設計は一度で終わりません。作成された設計図を同僚とレビューし、新しい脅威情報が出たら設計を継続的に改善する必要があります。
✨ 終わりに
安全でない設計は、アプリケーションの「先天的な心臓病」のようなものです。後で発見すると手術が非常に複雑で危険です。一方、開発初期に脅威を検討し、安全に設計することは、小さな努力で未来の大きな災害を防ぐ最も効果的な方法です。
「よくできたコードは安全な設計から生まれる」という言葉を忘れず、私たち全員が「セキュリティアーキテクト」という心構えで開発に取り組めればと思います!
コメントを残す