コードレビューで見つかった問題を、勉強のためにまとめたものです(修正済み)。
この記事でわかること
- 認証エンドポイントにレート制限を入れる重要性
- DRF Throttling と django-ratelimit の使い分け
概念
レート制限(Rate Limiting)とは、一定時間内にリクエストできる回数を制限する仕組みのこと。ログイン画面は 攻撃者が最も狙いやすいエントリーポイント であり、レート制限がなければパスワードの総当たり(ブルートフォース)攻撃が成立してしまいます。
修正前のコード
LoginView、SignupView、TokenRefreshCookieView にいずれもレート制限がなかった。
python
# 修正前
class LoginView(APIView):
permission_classes = [AllowAny]
@method_decorator(csrf_protect)
def post(self, request):
serializer = LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
username = serializer.validated_data['username']
password = serializer.validated_data['password']
user = authenticate(request, username=username, password=password)
# ...
# ← 何度でも試せる。失敗してもロックなしなぜ危険か
- パスワード総当たり: 1 秒間に数千リクエスト送信可能。よくあるパスワードを全試行されます
- アカウント大量作成: SignupView が無制限なのでスパムアカウントを大量生成できます
- トークン消耗攻撃: TokenRefreshView を叩き続けてブラックリストを消耗させられます
対策
綴Photo では DRF の ScopedRateThrottle を使い、認証エンドポイントごとに別々のレートを割り当てた。一律ではなく、ログインは厳しめ・トークン更新は緩め、とエンドポイントの性質に合わせて分けられるのが利点。
レート制限のやり方は大きく3つあり、どこまで細かく絞りたいかで選びます。
python
# settings/base.py — レートを「定義」する場所。scope 名ごとに上限を決める
REST_FRAMEWORK = {
# ScopedRateThrottle を使う宣言(scope 別にレートを分けられる方式=上の図の真ん中)
'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.ScopedRateThrottle'],
'DEFAULT_THROTTLE_RATES': {
'auth_login': '10/min', # ← この scope 名が View 側と対応する
'auth_signup': '5/min',
'auth_token_refresh': '60/min',
},
}python
# views.py — レートを「適用」する場所。View に scope を貼って効かせる
from rest_framework.throttling import ScopedRateThrottle
class LoginView(APIView):
throttle_classes = [ScopedRateThrottle] # この View で throttle を有効化
throttle_scope = 'auth_login' # ← settings の 'auth_login'(10/min) と名前で紐づくから効く
# ...django-ratelimit のような追加パッケージを入れなくても、scope を分けるだけでエンドポイント単位の制御ができます。
キャッシュの注意: DRF の throttle はカウントをキャッシュに持つ。
学びポイント
- 認証エンドポイントのレート制限は「機能を作ったらセットで入れる」もの。後回しにするほど対応コストが上がります
- DRF の Throttling は設定数行で入ります。まず
ScopedRateThrottleで全体に入れて、エンドポイントごとに scope でレートを調整するのがおすすめ AllowAnyなエンドポイントほど攻撃されやすいです。パーミッションと合わせてスロットリングをデフォルト設定にします
おわりに
レート制限なしの認証エンドポイントは、機能ゼロから実装した直後に最もよく発生する脆弱性。「ログイン作ったら忘れずレート制限」をチェックリストに入れます。
この記事は2026年4月時点の自分の理解で書いています。
django-ratelimitや DRF Throttling の設定方法は変化が速い領域なので、最新の公式ドキュメントも合わせて参照してください。