OWASP Top 10 を通じて、Webアプリケーションのセキュリティを学び直しています。
今回は、Insecure Design(安全性を考慮しない設計)についてまとめます。
Insecure Designとは、アプリの構造やルールづくりの段階で、安全性が考慮されていないことを指します。コードのバグではなく、「設計そのものの問題」が原因になります。
こちら、以前はなかった新しい項目です。生成AIを使ったコーディングでは特に注意が必要な項目といえます。

Laravelアプリケーション開発時の対策や、バイブコーディング(生成AIコーディング)でも役立つ対策も考えていきますね。
Insecure Design(安全性を考慮しない設計)
Insecure Design(安全性を考慮しない設計)について、公式説明ページはこちら:
Insecure Designとは、アプリの構造やルール作りの段階で、安全性を考慮していないことを指します。つまりコードのバグではなく、「設計そのものに問題がある」状態です。

セキュリティ対策を考えるうえで、結局この「設計段階」がいちばん大事だと思います。
どんなリスクがおこりうるか
Insecure Designによるリスクですが、たとえば、次のようなものが考えられます。
あるオンラインショップでは、人気のビデオカードが販売されていました。
開発者は指示通りに開発を進めましたが、このサイトには「1人あたりの購入上限」がありませんでした。
その結果、悪質な転売業者が自動購入ツールを使って大量購入。
本当に欲しかった一般ユーザーが買えず、ショップの信頼は失われてしまいました…。

さて、ここでの問題はなんでしょうか?
このオンラインショップの開発者は、仕様どおりに作業を進めたため、開発段階での落ち度とはいえません。
「1人あたりの購入上限を設ける」といったルールが設計段階で決まっていなかったことが、根本的な原因だと考えられます。
もし最初から「1人あたり1時間に1個まで」といったルールが定められていれば、次のような対策を実装することができました。
-
レート制限(一定時間あたりのリクエスト数制限)
-
IP アドレスやデバイス単位でのアクセス制御
-
認証済みユーザーのみ購入可能にする仕組み
たとえ気の利く開発者が部分的にこうした処理を入れたとしても、ルールが曖昧なままではどこかに穴が残る可能性があります。
このような設計段階での安全性の欠落リスクを取り上げたのが、Insecure Design(安全性を考慮しない設計)です。
CWE(共通脆弱性タイプ)
このカテゴリーに含まれる主なCWE(脆弱性分類)として、公式ページには次のものが挙げられています。
これらは「設計」というよりも実装の不備に近い印象がありますが、何か起こった時のリスクを最小限におさえるためには、こういった部分に注意が必要だと考えられます。
-
CWE-209: エラーメッセージからの情報漏洩
-
エラーメッセージにシステム内部の情報が含まれ、攻撃者にヒントを与える脆弱性
-
-
CWE-256: 保護されていない認証情報の保存
- パスワードや API キーなどを安全に保管せず、平文やコード内に埋め込む脆弱性
- CWE-501: 信頼境界線の侵害
- クライアント側から送られてきたデータ(価格、権限など)を検証せずに信頼してしまう脆弱性
-
CWE-522: 適切に保護されていないクレデンシャル
- パスワードやトークンを暗号化せずに送受信する脆弱性
対策としては、以前の記事【暗号化の失敗】なども関連してきます。
対策
このリスクに対して、下記のような対策が挙げられます。
- セキュアな開発ライフサイクルの確立
- プロジェクト初期からセキュリティ担当者や専門家と協力し、継続的にリスクを確認します。
- 安全な設計パターン・コンポーネントライブラリの整備
- 開発者が安全な実装を簡単に選べるように、検証済みのライブラリやテンプレートを用意します。
- 脅威モデル化の実施
- 重要な機能について、想定される攻撃・誤用パターンを洗い出します。
- ユーザーストーリーにセキュリティ要件を統合
- 正常に動作する場合だけでなく、異常時や、攻撃された場合のシナリオも含めて検討します。
- 各層での入力チェック
- フロントエンドだけでなく、バックエンドでも必ず入力値を検証します。
- 攻撃を想定したテストの実施
- 悪意ある使い方を想定したテストも行います。
- システムの層を分離
- Web層、アプリ層、データベース層などを適切に分離し、攻撃の影響を最小限にします。
- テナントの分離
- 複数の組織や企業が同じシステムを使う場合、お互いのデータが見えないように分離します。
- リソースの利用制限
- ユーザーやサービスが使えるリソース(リクエスト数、データ量など)に上限を設けます。
*分かりやすく書きなおしていますが、正確な元文章を確認したい場合は、OWASP公式サイトをご覧ください。
Laravelでの対策
今回の項目は、そもそもWebアプリ開発前の設計段階で考慮すべき内容です。
そのため、他のリスクのようにLaravel側で用意された機能で完全に防げるものではありません。
ただ、共通脆弱性タイプ(CWE)に関連する重要な実装ポイントとして、.envファイルの設定が挙げられます。
.envファイルの書き方
Laravelでは、.envファイルに環境変数を定義します。.envは、開発環境と本番環境で別々の設定を用意するのが基本です。
開発環境では、エラー時にエラーメッセージが表示されるようにします。
|
1 |
APP_DEBUG=true |
【エラーメッセージ表示】

本番環境では、この部分は次のように修正し、エラーメッセージが表示されないようにしておきます。
|
1 |
APP_DEBUG=false |
【エラーメッセージ非表示】

エラーメッセージにシステム情報を含めてしまうと、攻撃者にヒントを与える可能性があります。
そのため、本番ではエラー内容を画面に出さず、ログにのみ記録するのが原則です。
また、データベースやAPIキーなどの機密情報も、本番・開発でしっかり分けて管理することが大切です。

拙著「Laravelの教科書 バージョン12」をお持ちの方は、72ページ見てみてくださいね。.envで設定できる環境変数の書き方例を、開発環境と本番環境に分けて、紹介しています。
クリックするとamazonページへ。
↓↓↓
バイブコーディングでも役立つ全般的な注意点
今回のInsecure Designの考え方は、生成AIを使った開発でも重要です。
生成AIにコードを書いてもらう前に、しっかりと設計部分を自分で整理しておくこと。
これが安全な開発の第一歩です。
もちろん、この段階でも生成AIを活用することができます。
AIは実装担当(コーダー)として使うだけでなく、設計パートナーとして、セキュリティ観点を相談しながら仕様をまとめていくこともできます。

AIとの壁打ちイメージ
さいごに
Insecure Design(安全性を考慮しない設計)は、アプリケーションの根幹に関わるリスクです。
後から修正できない性質を持つため、最初の設計段階での判断がすべて!と言っても過言ではありません。

昔、わたしの祖母が「最初のボタンをかけ間違えると、最後のボタンも間違える」と言っていたことを思い出しました^^
開発の最初のボタンである設計部分、しっかりと考えていきたいですね。
-160x90.png)

