0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

URLの数字をひとつ変えたら、隣の人の個人情報が全部見えた

0
Posted at

そのAPI、認可チェックしてますか?

自社サービスのマイページ機能を実装した時の話です。プロフィール情報を取得するAPIのエンドポイントはこうなっていました。

GET /api/users/1052/profile

ある日、テスト中にふと思い立ち、URLの 10521053 に変えてブラウザのアドレスバーに叩き込んでみました。
表示されたのは、自分ではない見知らぬユーザーの氏名、メールアドレス、電話番号。
認証(ログインしていること)はチェックしていましたが、認可(そのデータにアクセスする権限があるか)は一切チェックしていなかったのです。
これが IDOR(Insecure Direct Object Reference:安全でない直接オブジェクト参照) と呼ばれる脆弱性です。OWASP Top 10の「Broken Access Control(アクセス制御の不備)」に分類され、バグバウンティ(脆弱性報奨金プログラム)で最も頻繁に報告される脆弱性の一つ
でもあります。

なぜ見落とされるのか

IDORの厄介さは、コードとしては正常に動いている点にあります。
リクエストを受け取り、DBからデータを引き、レスポンスを返す。ロジックにバグはありません。ただ「その人がそのデータを見ていい人か?」の1行が抜けているだけです。

# 脆弱なコード
@app.get("/api/users/{user_id}/profile")
def get_profile(user_id: int, current_user = Depends(get_current_user)):
    return db.query(User).filter(User.id == user_id).first()
    # ↑ current_user と user_id の一致をチェックしていない!
# 安全なコード
@app.get("/api/users/{user_id}/profile")
def get_profile(user_id: int, current_user = Depends(get_current_user)):
    if current_user.id != user_id:
        raise HTTPException(status_code=403, detail="Forbidden")
    return db.query(User).filter(User.id == user_id).first()

防御策

1. 全てのAPIエンドポイントで「認可チェック」を義務化する
認証(Authentication)だけでなく、認可(Authorization)が漏れていないかをコードレビューのチェックリストに入れましょう。
2. IDを連番にしない(UUIDの採用)
/users/1052 のような連番IDは、攻撃者が「+1して次のユーザーを見る」という予測を容易にします。UUIDv4(550e8400-e29b-41d4-a716-446655440000)を使えば推測が困難になります。ただし、UUIDにしたからといって認可チェックを省略してはいけません。あくまで「推測困難にする」だけであり、根本的な対策ではありません。
3. 自動テストで認可漏れを検出する
「ユーザーAのトークンで、ユーザーBのリソースにアクセスしたら403が返ること」というテストケースを、全エンドポイントに対して書きましょう。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?