mcpField
R
rate-limiting-abuse-protection

rate-limiting-abuse-protection

github.com/patricio0312revセキュリティ63320 回インストール41 週間前に更新
リポジトリ

rate-limiting-abuse-protection について

rate-limiting-abuse-protectionは、過剰なリクエストや不正利用からAPIを保護する開発者向けのスキルです。複数の制限方式と、ユーザー、IP、Redisの状態を使った実装方法を紹介します。

主な機能

  1. 01固定ウィンドウやスライディングウィンドウなどの方式
  2. 02Expressのレート制限ミドルウェア例
  3. 03Redisによる制限チェック
  4. 04ユーザーまたはIP単位のリクエスト制限
  5. 05レート制限レスポンスヘッダーの返却

活用シーン

  1. 01APIエンドポイントごとのリクエスト制限
  2. 02ユーザーごとのリクエスト枠の設定
  3. 03不審なIPのブロックと違反記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/patricio0312rev/skills --skill rate-limiting-abuse-protection

インストール後、Claude Code で/rate-limiting-abuse-protectionを入力して読み込まれたか確認します。

詳細

レート制限と不正利用対策

インテリジェントなレート制限で、API を不正利用から保護します。

レート制限の戦略

固定ウィンドウ:1 時間あたり 100 リクエスト スライディングウィンドウ:より正確で、バーストを防止します トークンバケット:上限までのバーストを許可します リーキーバケット:リクエストレートを平滑化します

実装(Express)

import rateLimit from "express-rate-limit";

// Global rate limit
const globalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // 100 requests per window
  message: "Too many requests, please try again later",
  standardHeaders: true, // Return rate limit info in headers
  legacyHeaders: false,
});

// Stricter limit for auth endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // Only 5 attempts
  skipSuccessfulRequests: true, // Don't count successful logins
});

app.use("/api/", globalLimiter);
app.use("/api/auth/login", authLimiter);

Redis ベースのレート制限

import Redis from "ioredis";

const redis = new Redis();

export const checkRateLimit = async (
  key: string,
  max: number,
  window: number
): Promise<{ allowed: boolean; remaining: number }> => {
  const now = Date.now();
  const windowStart = now - window;

  await redis
    .multi()
    .zremrangebyscore(key, 0, windowStart)
    .zadd(key, now, `${now}`)
    .zcard(key)
    .expire(key, Math.ceil(window / 1000))
    .exec();

  const count = await redis.zcard(key);

  return {
    allowed: count <= max,
    remaining: Math.max(0, max - count),
  };
};

ユーザーごとのレート制限

export const userRateLimit = (max: number, window: number) => {
  return async (req, res, next) => {
    if (!req.user) return next();

    const key = `rate_limit:user:${req.user.id}`;
    const result = await checkRateLimit(key, max, window);

    res.setHeader("X-RateLimit-Limit", max);
    res.setHeader("X-RateLimit-Remaining", result.remaining);

    if (!result.allowed) {
      return res.status(429).json({
        error: "Rate limit exceeded",
        retryAfter: window / 1000,
      });
    }

    next();
  };
};

IP ベースの保護

// Block suspicious IPs
const ipBlocklist = new Set<string>();

export const checkIPReputation = async (ip: string): Promise<boolean> => {
  if (ipBlocklist.has(ip)) return false;

  // Check against threat intelligence API
  const reputation = await checkThreatIntel(ip);
  if (reputation.isMalicious) {
    ipBlocklist.add(ip);
    return false;
  }

  return true;
};

レスポンスヘッダー

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000
Retry-After: 3600

ベストプラクティス

  • エンドポイントごとに異なる制限を設定する
  • 負荷の高い操作には、より低い制限を設定する
  • 内部サービスにはレート制限を適用しない
  • 有用なエラーメッセージを返す
  • レート制限違反をログに記録する
  • 不正利用のパターンを監視する
  • 信頼できる IP を許可リストに追加する

出力チェックリスト

  • レートリミッターミドルウェア
  • ルートごとのポリシー
  • ユーザーベースの制限
  • IP ベースの制限
  • レート制限ヘッダー
  • 安全なエラーレスポンス
  • 可観測性/ログ記録
  • 内部サービス向けのバイパス

コメント