【実務・中級編】Insecure Design: セキュリティ要件定義における脅威モデリングの実施 – アプリケーションセキュリティ & 安全な開発防御ガイド

「後から直す」は死へのカウントダウン:STRIDEで読み解く「設計段階の脆弱性」

現場でインシデント対応をしていると、いつも同じ光景に出くわす。「脆弱性診断で致命的な穴が見つかりました、至急修正してください」という悲痛な叫びだ。しかし、コードを読み進めると気づく。これはバグではなく、「最初からそう設計されている」という悲劇であることがほとんどだ。

OWASP Top 10の筆頭に躍り出た「Insecure Design(不完全な設計)」。これはパッチを当てて解決する類のものではない。設計思想そのものが攻撃者に利するように仕組まれている状態を指す。今日は、この「負け戦」を回避するための武器、STRIDEモデルを用いた脅威モデリングについて、泥臭い実戦の視点から解説する。

—

1. なぜ「設計」でコケるのか?

多くのエンジニアは「実装のバグ(SQLiやXSS)」には敏感だ。しかし、「仕様上の欠陥」は見過ごされる。例えば、「管理者権限の確認をフロントエンドのJavaScriptだけで行っている」システム。これは実装バグではなく、設計ミスだ。

攻撃者は、ソースコードを読む前に「設計図」を想像する。
「この画面でこのボタンを押すと、バックエンドでこのAPIが叩かれるはずだ。なら、そのAPIを直接叩いたらどうなる?」
この思考プロセスが攻撃の第一歩だ。我々もこれと同じ思考を持つ必要がある。それが脅威モデリングだ。

—

2. STRIDEモデル:攻撃者の視点を手に入れる

STRIDEは、システムを6つのカテゴリーで「壊す方法」を考えるフレームワークだ。

  • Spoofing(なりすまし): IDを偽装できるか?
  • Tampering(改ざん): リクエストの中身を書き換えられるか?
  • Repudiation(否認): 証拠を消せるか?
  • Information Disclosure(情報漏洩): 権限のないデータにアクセスできるか?
  • Denial of Service(サービス拒否): リソースを枯渇させられるか?
  • Elevation of Privilege(権限昇格): 一般ユーザーが管理者になれるか?

実戦的な脅威モデリングの進め方

ホワイトボードでもJiraのチケットでもいい。「この機能、なりすましができるとしたらどこから?」とチームで問いかける。例えば、「パスワードリセット機能」なら、「メールアドレスを知っていれば他人のパスワードを勝手に変更できるのではないか?」というTamperingの可能性を洗い出す。

—

3. 実装の鉄則:設計ミスを殺すコード

設計段階で「不整合」を防ぐための具体例を見てみよう。ここでは、「権限昇格(E-P)」を防ぐための最も重要な考え方である「サーバーサイドでの再検証」をコードに示す。

Python (FastAPI) での実装例

フロントエンドを信じず、必ずセッションまたはトークンから「認可」を行うこと。

from fastapi import Depends, HTTPException, status
from typing import Optional

ユーザー権限を確認するための依存関係
async def verify_admin_role(current_user: User = Depends(get_current_user)):
# ここが設計の肝:クライアントからの入力を信じない
# DBの最新情報を元に権限を判定する
if current_user.role != “admin”:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=”管理者権限が必要です”
)
return current_user

保護されたエンドポイント
@app.post(“/admin/delete-user/{user_id}”)
async def delete_user(user_id: int, admin: User = Depends(verify_admin_role)):
# 認可が通った場合のみ実行される
return db.delete_user(user_id)

—

4. インフラレベルでの防御(Nginx設定)

設計の不備をインフラで補完するケースもある。例えば、機密性の高いエンドポイントへのアクセスを制限するのも「設計」の一部だ。

Nginxの設定で特定のディレクトリをIP制限する(社内ツール等)
location /admin/ {
# 信頼できるIPアドレスのみを許可
allow 192.168.1.0/24;
# それ以外は403 Forbidden
deny all;

# ヘッダーによる情報の断片化を防ぐ(情報漏洩対策)
proxy_hide_header X-Powered-By;
add_header X-Content-Type-Options nosniff;
}

—

5. 最後に:セキュリティは「お守り」ではない

脅威モデリングは、一度やって終わりではない。仕様変更があるたびに、STRIDEの視点で「新しい穴が開いていないか」を問い直すのがプロの仕事だ。

「面倒くさい」と感じたなら、それはまだ危機感が足りない。インシデント対応で徹夜し、顧客への謝罪文を書き、フォレンジック調査に多額の予算を投じることの方が、遥かに面倒でコストがかかる。

設計段階で「もしもここが攻撃されたら?」と想像するクセをつけること。それが、あなたの開発するシステムを、そしてあなた自身をリスクから守る唯一の道だ。

さあ、次の設計会議では、一番意地悪な攻撃者の視点を持って参加してくれ。現場からは以上だ。

コメント

タイトルとURLをコピーしました