Saltar al contenido

Lección 8 de 25 · Lectura y práctica

Aplicar Medidas de Seguridad: CORS, Rate Limiting y Validación

Tipo de lección: VideoConcepto claveEn el desarrollo de APIs modernas, la seguridad no es un lujo sino una necesidad fundamental. CORS (Cross-Origin Resource Sharing), Rate Limiting y Validación forman una trinidad defensiva que.

Del concepto a la práctica

Taller de esta lección

Estos controles resuelven riesgos distintos. CORS limita qué navegador puede leer respuestas, el rate limiting limita frecuencia y la validación restringe forma y tamaño de los datos. Ninguno reemplaza la autenticación. Para una ruta de comentarios, se puede aceptar solo el origen local autorizado y un máximo de cinco solicitudes por minuto en el laboratorio.

Ejemplo resuelto

Un cuerpo con body de 900 caracteres se rechaza si el máximo es 500. Con un contador inicialmente vacío y seis cuerpos válidos desde el mismo identificador dentro de una ventana de 60 segundos, se reciben cinco respuestas normales y una 429. Mantén separada la prueba de longitud inválida para no alterar el contador de este caso.

Pruébalo

  1. Configura una lista explícita de orígenes.

  2. Define el límite y la ventana en configuración.

  3. Valida longitud, campos obligatorios y valores permitidos.

  4. Envía casos válido, demasiado largo y sexto intento.

Comprueba tu resultado

El caso válido pasa; el largo devuelve 422; el sexto intento de la prueba aislada devuelve 429. Un cliente fuera del navegador no queda bloqueado por CORS. Un contador solo en memoria cubre un proceso: para varios workers se necesita estado compartido o un límite en la puerta de entrada, con política definida.

Error frecuente: usar allow_origins=["*"] junto con credenciales. Corrígelo declarando orígenes concretos y prueba el encabezado de origen permitido.

Capas de acceso, actualización, copias y respuesta a incidentes alrededor de un sistema.
CursaloMapa de práctica
La seguridad necesita varias capas

El control de acceso, las actualizaciones y las copias de seguridad cubren riesgos distintos. Una alerta necesita un procedimiento de respuesta para contener y recuperar el servicio. Varias capas reducen la exposición, pero ninguna garantiza seguridad absoluta.

Ver la infografía en tamaño completo ↗

Tipo de lección: Video

Concepto clave

En el desarrollo de APIs modernas, la seguridad no es un lujo sino una necesidad fundamental. CORS (Cross-Origin Resource Sharing), Rate Limiting y Validación forman una trinidad defensiva que protege tu API desde diferentes ángulos. Imagina tu API como un edificio de oficinas: CORS es el sistema de control de acceso que decide quién puede entrar desde qué puertas, Rate Limiting es el guardia que evita que demasiadas personas entren al mismo tiempo causando caos, y la Validación es el detector de metales que revisa que nadie lleve objetos peligrosos.

CORS especifica qué dominios externos pueden consumir tu API, previniendo ataques de CSRF y protegiendo datos sensibles. Rate Limiting controla la cantidad de solicitudes que un cliente puede hacer en un período determinado, protegiendo contra ataques de denegación de servicio (DDoS) y abuso de recursos. La Validación asegura que los datos entrantes cumplan con las reglas de negocio antes de procesarlos, evitando inyecciones y corrupción de datos.

Cómo funciona en la práctica

Implementar estas medidas en FastAPI sigue un patrón claro. Primero, configuras CORS usando fastapi.middleware.cors para definir orígenes permitidos, métodos HTTP y headers. Luego, integras Rate Limiting con bibliotecas como slowapi o fastapi-limiter para establecer límites por IP, usuario o endpoint. Finalmente, aplicas Validación exhaustiva usando los modelos Pydantic de FastAPI, combinando validadores nativos con custom validators.

Veamos el flujo completo: cuando una solicitud llega a tu API, primero pasa por el middleware CORS que verifica si el origen está permitido. Si pasa, el middleware de Rate Limiting revisa si el cliente no ha excedido sus cuotas. Solo entonces la solicitud llega al endpoint, donde Pydantic valida automáticamente los datos según tus modelos. Este enfoque por capas crea defensas profundas.

Código en acción

Configuración completa de seguridad en FastAPI:

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field, validator
from typing import Optional
import time

# Configuración CORS
app = FastAPI(title="API Segura")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://mi-frontend.com", "http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["Authorization", "Content-Type"],
)

# Implementación básica de Rate Limiting
from collections import defaultdict
from datetime import datetime, timedelta

request_log = defaultdict(list)
RATE_LIMIT = 100  # solicitudes por hora
TIME_WINDOW = 3600  # segundos

def rate_limit_middleware(client_ip: str):
    now = datetime.now()
    window_start = now - timedelta(seconds=TIME_WINDOW)
    
    # Filtrar solicitudes dentro de la ventana
    recent_requests = [req_time for req_time in request_log[client_ip] 
                      if req_time > window_start]
    
    if len(recent_requests) >= RATE_LIMIT:
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail="Límite de tasa excedido"
        )
    
    request_log[client_ip].append(now)
    # Limpiar registros antiguos
    request_log[client_ip] = [req for req in request_log[client_ip] 
                             if req > window_start]

# Modelo con validación avanzada
class UserCreate(BaseModel):
    email: str = Field(..., min_length=5, max_length=100)
    password: str = Field(..., min_length=8, max_length=100)
    age: Optional[int] = Field(None, ge=18, le=120)
    
    @validator('email')
    def validate_email(cls, v):
        if '@' not in v:
            raise ValueError('Email inválido')
        return v.lower()
    
    @validator('password')
    def validate_password(cls, v):
        if not any(c.isupper() for c in v):
            raise ValueError('La contraseña debe contener al menos una mayúscula')
        if not any(c.isdigit() for c in v):
            raise ValueError('La contraseña debe contener al menos un número')
        return v

@app.post("/users/")
async def create_user(user: UserCreate, client_ip: str = Depends(lambda: "127.0.0.1")):
    # Aplicar rate limiting
    rate_limit_middleware(client_ip)
    
    # La validación ya ocurrió automáticamente gracias a Pydantic
    return {"message": "Usuario creado", "email": user.email}

Errores comunes

  • Configurar CORS demasiado permisivo: Usar allow_origins=["*"] en producción expone tu API a ataques. Siempre especifica dominios exactos.
  • Rate Limiting sin diferenciación de endpoints: Aplicar el mismo límite a todos los endpoints puede afectar la UX. Endpoints críticos como login necesitan límites más estrictos.
  • Validación incompleta: Confiar solo en validación del frontend. La validación debe ocurrir siempre en el backend, donde tienes control total.
  • No limpiar logs de Rate Limiting: Acumular registros indefinidamente consume memoria. Implementa limpieza periódica como se muestra en el ejemplo.
  • Ignorar headers de CORS: No configurar allow_headers correctamente puede bloquear solicitudes legítimas con headers personalizados.

Checklist de dominio

  1. ¿Configuraste CORS especificando dominios exactos en lugar de usar "*"?
  2. ¿Implementaste Rate Limiting con límites diferenciados por tipo de endpoint?
  3. ¿Validas todos los datos de entrada con Pydantic, incluyendo custom validators?
  4. ¿Probaste tu configuración CORS desde diferentes orígenes?
  5. ¿Monitorizas las solicitudes bloqueadas por Rate Limiting para ajustar límites?
  6. ¿Incluiste mensajes de error claros cuando falla la validación?
  7. ¿Documentaste tus políticas de seguridad para el equipo?

Implementar API segura con FastAPI

Construye una API REST completa que implemente las tres medidas de seguridad aprendidas. Sigue estos pasos:

  1. Crea un nuevo proyecto FastAPI con un endpoint /products/ que acepte POST para crear productos
  2. Configura CORS para permitir solo estos orígenes: https://tienda.com y http://localhost:8080
  3. Implementa Rate Limiting que permita máximo 50 solicitudes por hora por IP para el endpoint de productos
  4. Crea un modelo Pydantic para Producto con estas validaciones:
    • Nombre: entre 3 y 100 caracteres
    • Precio: mayor que 0 y menor que 1000000
    • Categoría: debe ser una de estas: "electronica", "ropa", "hogar"
    • Stock: entero no negativo
  5. Agrega un custom validator que verifique que productos de categoría "electronica" tengan precio mayor a 100
  6. Prueba tu implementación con diferentes casos: orígenes permitidos/no permitidos, exceso de solicitudes, datos inválidos
Pistas
  • Usa Enum de Python para las categorías válidas
  • Considera usar bibliotecas como slowapi para Rate Limiting más robusto
  • Prueba los headers CORS con herramientas como curl o Postman

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con Dominio Profesional de FastAPI: Construcción de APIs Escalables y Seguras

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.