IDOR
- 認可の不足や漏れで他ユーザーのリソースなどを不正に閲覧できること
- 認証してるからOKではなく、認可も正しく行う必要がある
- 認証だけではなく認可もする
SSRF
- サーバーから意図しない外部リソースへのリクエストを起こすもの
- ユーザーから受け取った値を元にHTTPリクエストは疑う
- そもそもクライアントサイドからのリクエストで事足りるもの(画像表示など)はサーバーサイドを経由しないべき
- クライアントサイドからの処理であれば、ユーザーの端末からのリクエストとなるため考慮することが減る
設定のミス
- Weak Credentials、Default Credentials、最小権限の原則
- 何をユーザーに見せるのか?が大切
- 脆弱な設定を便利として扱っているなら構造を見直す必要がありそう
Software Supply Chain Attack
- ちょっと前よく話題になっていたもの
- 暫定的には公式に従いVerUPが必要だと思うが、そもそもその依存関係が本当に必要か?や、CIでauditするなど構造的解決が必要
ワーク
問題
- 所有者チェックを「書き忘れ」が起きない場所に置くには、どこに判定を寄せればよいか。 操作そのものに埋められないか。
仮説
- 個人のブログツールで他のユーザーにはみられないとする。
- 現状の投稿詳細画面のコード。
# 元の実装想定
post = Post.find(id: {id})
if (!post.user.id == {認証しているuser_id}) return
# ~後続で投稿を表示する処理~
# 改善案の仮説
myPost = Post.getMyPost(user_id: {user_id})
post = myPost.find(id: {id})
# ~後続で投稿を表示する処理~
AI改善提案とフィードバック
- 取得してから弾くを、自分の投稿からしか取れないにしたのは⭕️
- user_id がただの値(整数や文字列)なので、「どこから来たか」を型が区別できなかったことは❌
- params[:id] のような信頼できない値も、User.find(...) で取ってきた他人のIDも、照合済みのIDと同じように渡せた
- 文字列だからではない。整数でも User オブジェクトでも、出どころを表していない限り同じ問題が起きる。型ならOKではない
# 認証モジュール内
# セッションストアを引く。無い・期限切れなら失敗 → 成功すれば ログイン中ユーザー(user_id) を返す
ログイン中ユーザー.セッションから作る(session_id)
# 投稿詳細画面の実装
# DBへの問い合わせ自体を「id一致 かつ user_id一致」にする → 見つからなければ404
post = Post.findMine(user: {ログイン中ユーザー}, id: {id})
