Shikata Ga Nai

Private? There is no such things.

信頼しすぎたユーザーの裏切り ― 想定外の動きが招くロジック脆弱性

Hello there, ('ω')ノ

🔍 脆弱性の核心:「ユーザーは正しく使うはず」という思い込み

多くのアプリケーションでは、次のような楽観的な設計が行われてしまいます:

✅ 最初にチェックを通過したなら、その後も正しい動きをしてくれるはず。

しかし、これは非常に危険な前提です。


❌ よくある誤った前提とその危険性

誤った前提 実際に起きること
一度ログインしたら信頼できる ログイン後のパラメータを改ざんされる
最初のフォームで正しい入力をしている 後のリクエストで不正な値を送ってくる
購入ページを通ってから支払いする 支払いページに直接アクセスされる

💣 例:チェックアウトフローのロジック抜け穴

  1. カートに商品を追加
  2. サーバー側で「在庫確認」「金額計算」など厳密な検証
  3. フロントエンドからの支払い処理リクエストにトークン付きで進行

ここで「支払いリクエスト」が次のように単純だと:

POST /purchase
product_id=123&amount=0.01

→ ユーザーが直接POSTリクエストを再送・改変すれば、1円で購入できる可能性がある!


✅ 検証時に注目すべきポイント

チェック項目 解説
複数ステップで必要な検証がすべてのリクエストに存在するか 金額ユーザー権限 などが後段でも検証されているか?
トークンや一時的なIDの再利用ができないか 期限付きのトークンが無期限に使えないか?
検証がクライアント側のみで行われていないか JavaScriptでしかチェックしてない場合は危険

🛠 Burpでの検証アプローチ

  1. 正規の操作フローを1回実行してBurpで記録
  2. 各ステップのリクエストをRepeaterに送信
  3. 順番を飛ばす、金額を変更する、トークンを再利用するなど改変
  4. サーバーの挙動を観察して不整合が起きるか確認

🎓 まとめ:ビジネスロジック脆弱性を防ぐには?

  • 常に「悪意あるユーザーがいる」前提で設計する
  • サーバー側での再検証を全処理に徹底
  • 入力値だけでなく、ユーザー状態・順序・頻度なども検証対象とする
  • フロー内の重要ステップはステートフルに管理する(例:トークン必須)

Best regards, (^^ゞ