ScaleRocket/Web

Rate Limiting

Rate limiting côté client, limites intégrées de Supabase et patterns de rate limiting pour les Edge Functions.

Vue d'ensemble

Le rate limiting protège votre application contre les abus, les attaques par force brute et l'utilisation excessive de l'API. ScaleRocket implémente le rate limiting à plusieurs niveaux : throttling côté client, limites intégrées de Supabase et rate limiting personnalisé dans les Edge Functions.

Rate limiting côté client

Throttling de connexion

Le formulaire de connexion empêche les soumissions rapides successives avec un cooldown côté client :

const [isSubmitting, setIsSubmitting] = useState(false);

const handleLogin = async (e: FormEvent) => {
  e.preventDefault();
  if (isSubmitting) return;

  setIsSubmitting(true);
  try {
    await supabase.auth.signInWithPassword({ email, password });
  } catch (error) {
    toast({ title: "Login failed", variant: "destructive" });
  } finally {
    setTimeout(() => setIsSubmitting(false), 2000); // 2s cooldown
  }
};

Cela empêche les requêtes dupliquées mais ne protège pas contre les attaquants déterminés. Le rate limiting côté serveur est essentiel.

Limites intégrées de Supabase

Supabase applique des limites de débit automatiques aux endpoints d'authentification :

EndpointLimite par défaut
Inscription10 requêtes par heure par IP
Connexion30 requêtes par heure par IP
Réinitialisation de mot de passe5 requêtes par heure par IP
OAuth10 requêtes par minute par IP
API (PostgREST)Configurable par projet

Ces limites sont appliquées côté serveur par Supabase. Vous pouvez ajuster certaines d'entre elles dans les paramètres de votre projet Supabase sous Auth > Rate Limits.

Rate limiting des Edge Functions

Pour les Edge Functions personnalisées, implémentez le rate limiting avec un store en mémoire ou une solution basée sur Redis.

Pattern simple en mémoire

// supabase/functions/_shared/rate-limit.ts
const requests = new Map<string, { count: number; resetAt: number }>();

export function isRateLimited(key: string, maxRequests = 10, windowMs = 60000): boolean {
  const now = Date.now();
  const entry = requests.get(key);

  if (!entry || now > entry.resetAt) {
    requests.set(key, { count: 1, resetAt: now + windowMs });
    return false;
  }

  entry.count++;
  return entry.count > maxRequests;
}

Utilisation dans une Edge Function

import { isRateLimited } from "../_shared/rate-limit.ts";

Deno.serve(async (req) => {
  const clientIP = req.headers.get("x-forwarded-for") || "unknown";

  if (isRateLimited(clientIP, 20, 60000)) {
    return new Response(JSON.stringify({ error: "Too many requests" }), {
      status: 429,
      headers: { "Content-Type": "application/json", "Retry-After": "60" },
    });
  }

  // Handle the request
});

Limitations

Le rate limiting en mémoire se réinitialise lors d'un cold-start de la fonction. Pour un rate limiting persistant, utilisez :

  • Table Supabase : Stockez les compteurs de requêtes dans une table de base de données avec un cron de nettoyage.
  • Upstash Redis : Utilisez @upstash/ratelimit pour un rate limiting distribué et adapté au serverless.

Recommandations pour la production

  1. Toujours activer les limites d'authentification Supabase -- elles sont activées par défaut ; ne les désactivez pas.
  2. Ajouter du rate limiting à toutes les Edge Functions publiques -- en particulier les webhooks et les endpoints de paiement.
  3. Utiliser des délais progressifs -- augmentez le temps de cooldown après des échecs répétés (backoff exponentiel).
  4. Retourner des codes de statut 429 -- incluez un en-tête Retry-After pour que les clients sachent quand réessayer.
  5. Surveiller les hits de rate limit -- loggez quand les utilisateurs atteignent les limites pour détecter les patterns d'abus.
  6. Utiliser Cloudflare ou Vercel WAF -- pour le rate limiting au niveau IP avant que les requêtes n'atteignent votre application.

Conseils

  • Le rate limiting côté client est une amélioration UX, pas une mesure de sécurité. Appliquez toujours les limites côté serveur.
  • Évitez le rate limiting par user ID uniquement ; un attaquant peut passer d'un compte à l'autre. Utilisez le rate limiting basé sur l'IP comme première couche.
  • Pour les endpoints API payants, envisagez un rate limiting par clé API lié au plan de l'utilisateur.

Fini ? Marquez cette page comme terminée.

On this page