Saltar al contenido

Seguridad de APIs REST: autenticación, rate limiting y el OWASP API Top 10

    Seguridad de APIs REST:

    autenticación, rate limiting y el OWASP API Top 10

    Seguridad de aplicaciones web  |  unfantasmaenelsistema.com

    Durante años la superficie de ataque de una aplicación web era su navegador: formularios, cookies, páginas renderizadas en el servidor. Hoy la lógica vive en el cliente —una SPA, una app móvil, un servicio que llama a otro— y todo lo que importa pasa por una API REST. Esa API es la puerta real a los datos, y a menudo está peor protegida que la web que la consume, porque se diseñó pensando en «nuestro propio front» y no en un atacante que habla HTTP directamente contra los endpoints.

    El proyecto OWASP mantiene una lista específica para este mundo, el API Security Top 10, porque los fallos que dominan aquí no son los mismos que en la web clásica. La inyección y el XSS ceden el protagonismo a los fallos de autorización objeto a objeto, a la exposición excesiva de datos y a la falta de límites. En este artículo recorremos esa lista, vemos cómo se autentica una API moderna y cómo el rate limiting deja de ser un lujo para convertirse en un control de seguridad.

    Qué aprenderás en este artículo

    Por qué BOLA/IDOR es el fallo número uno de las APIs y cómo se cierra · Las opciones de autenticación: API keys, OAuth2 client credentials y mTLS · Cómo el rate limiting y las cuotas frenan abuso, fuerza bruta y fuga masiva de datos · Validación de esquema con OpenAPI como barrera de entrada · El OWASP API Security Top 10 (2023) resumido en una tabla: ejemplo y defensa de cada punto

    1. BOLA / IDOR: el fallo que encabeza la lista

    Broken Object Level Authorization (BOLA), conocido tradicionalmente como IDOR (Insecure Direct Object Reference), es el primer punto del Top 10 y con diferencia el más frecuente. La idea es simple: un endpoint recibe un identificador de recurso —GET /api/invoices/4187— comprueba que quien llama está autenticado, pero no comprueba que ese recurso concreto le pertenezca. Cambiar el 4187 por 4188 devuelve la factura de otro cliente.

    Es tan común porque la autorización a nivel de objeto hay que escribirla explícitamente en cada controlador, mientras que la autenticación se resuelve una vez en un middleware global. El código «funciona» en todas las pruebas manuales porque el desarrollador siempre pide sus propios recursos.

    • Usar identificadores no predecibles (UUID v4) ayuda contra el escaneo secuencial, pero no es la defensa: un ID filtrado en un log o en otra respuesta sigue siendo utilizable
    • La defensa real es una comprobación de propiedad en cada acceso: WHERE id = :id AND owner_id = :usuario_actual, o una capa de autorización centralizada que reciba el recurso y el sujeto
    • Aplica igual a objetos anidados: /api/users/me/cards/12 debe verificar que la tarjeta 12 es de me, no solo que exista

    2. Autenticación de APIs: keys, OAuth2 y mTLS

    Antes de autorizar hay que identificar a quien llama. Según sea una persona a través de una app, un servicio automatizado o un socio externo, el mecanismo cambia.

    2.1 API keys

    Una cadena secreta larga que el cliente envía en cada petición, normalmente en una cabecera (Authorization: Bearer … o una cabecera propia). Identifican a la aplicación, no al usuario, y no llevan información de permisos por sí mismas. Son cómodas para empezar y para tráfico servidor a servidor, pero tienen puntos débiles: se filtran con facilidad (repositorios, logs, apps móviles descompiladas), no caducan solas y suelen concederse con demasiado alcance. Si se usan, deben poder rotarse, tener permisos mínimos y estar asociadas a un origen o rango de IP cuando sea posible.

    2.2 OAuth2 y OpenID Connect

    El estándar de facto para APIs que actúan en nombre de un usuario. El cliente no maneja la contraseña: obtiene un token de acceso de vida corta de un servidor de autorización y lo presenta a la API. Para tráfico entre servicios sin usuario, el flujo client credentials entrega un token a partir de un identificador y un secreto de cliente. La API valida el token (firma, exp, aud, iss, scope) en cada petición. Es más maquinaria, pero desacopla la emisión de credenciales del consumo y permite revocar y acotar por scope.

    2.3 mTLS (TLS mutuo)

    En TLS normal solo el servidor presenta certificado. En mTLS también lo hace el cliente, y la API solo acepta conexiones de certificados que reconoce. Es la opción más fuerte para un número acotado de clientes conocidos (integraciones B2B, microservicios dentro de una malla) porque la identidad va atada al canal y no a un secreto que se pueda copiar y reproducir. A cambio, gestionar el ciclo de vida de los certificados —emisión, rotación, revocación— tiene coste operativo.

    MecanismoIdentifica aCaso de uso idealPunto débil
    API keyLa aplicaciónServidor a servidor sencillo, planes de desarrolladorSe filtra fácil, no caduca sola, alcance excesivo
    OAuth2 (usuario)El usuario vía clienteApps y SPAs que actúan en nombre de alguienComplejidad; errores al validar el token
    OAuth2 client credentialsEl servicio clienteTráfico entre servicios con autorizaciónSecreto de cliente mal custodiado
    mTLSEl cliente (certificado)Integraciones B2B, malla de serviciosGestión de certificados a escala

    3. Exposición excesiva de datos y de funciones

    Dos puntos del Top 10 comparten una misma raíz: la API devuelve o acepta más de lo que debería porque confía en que el cliente «ya filtrará».

    3.1 Excessive Data Exposure

    El endpoint serializa el objeto entero de base de datos —user con su hash de contraseña, su token de recuperación, sus notas internas— y el front solo muestra el nombre. El dato viaja igualmente en la respuesta y cualquiera que mire el tráfico lo ve. La defensa es definir explícitamente qué campos salen: un DTO o esquema de respuesta por endpoint, nunca un return objeto directo.

    3.2 Broken Function Level Authorization

    El cliente legítimo nunca llama a DELETE /api/users/99 ni a /api/admin/…, así que esos endpoints se protegen «por oscuridad». Un atacante que lee el JavaScript de la SPA o prueba verbos HTTP encuentra la función administrativa y comprueba que solo exige estar autenticado, no ser admin. Cada endpoint debe declarar el rol o permiso que necesita, y el estado por defecto debe ser denegar.

    3.3 Mass Assignment

    Si el endpoint de «editar mi perfil» hace user.update(datos_del_body) sin lista blanca, el atacante añade «role»: «admin» o «account_balance»: 999999 al JSON y el ORM lo persiste. Acepta solo los campos que el usuario puede tocar, de forma explícita.

    4. Rate limiting y cuotas: un control de seguridad, no solo de capacidad

    Unrestricted Resource Consumption es otro punto del Top 10. Sin límites por cliente, una API expone varios problemas a la vez: fuerza bruta contra el login, enumeración de identificadores para explotar un BOLA a escala, extracción masiva de datos (scraping), coste descontrolado en endpoints que llaman a servicios de pago (envío de SMS, IA, terceros) y denegación de servicio con peticiones caras.

    4.1 Niveles de límite

    • Rate limit de ráfaga: peticiones por segundo/minuto y por clave de cliente (token, API key, IP como último recurso). Suele implementarse con token bucket o ventana deslizante
    • Cuota de largo plazo: total diario o mensual por plan; separa al usuario normal del que intenta descargarse toda la base de datos
    • Límites específicos más estrictos en endpoints sensibles: login, recuperación de contraseña, generación de informes, cualquier cosa que dispare gasto
    • Límites de tamaño: longitud máxima del cuerpo, profundidad de JSON, número de elementos en un array, para frenar payloads diseñados para agotar CPU o memoria

    4.2 Cabeceras y comportamiento esperado

    Una API educada informa del límite en cada respuesta y responde 429 Too Many Requests al superarlo, con una cabecera Retry-After. Así los clientes legítimos pueden adaptarse en lugar de reintentar en bucle.

    # Respuesta con informacion de limite (cabeceras habituales)
    HTTP/1.1 200 OK
    RateLimit-Limit: 100
    RateLimit-Remaining: 12
    RateLimit-Reset: 27
     
    # Al superar el limite
    HTTP/1.1 429 Too Many Requests
    Retry-After: 27
    Content-Type: application/json
     
    { "error": "rate_limited", "message": "Vuelve a intentarlo en 27 segundos" }

    El límite se aplica por identidad, no solo por IP

    Limitar solo por IP castiga a oficinas y operadores con NAT y no frena a un atacante con IPs rotativas · El contador debe ir asociado a la credencial (token, API key, cuenta) y, en endpoints anónimos como el login, combinar IP + identificador de usuario objetivo · Detrás de un proxy o CDN, usa la IP real de una cabecera de confianza que tú controles, no la que llegue sin validar

    5. SSRF y gestión de inventario

    5.1 Server-Side Request Forgery

    Muchas APIs aceptan una URL del usuario para «importar desde», «webhook» o «previsualizar enlace». Si el servidor hace esa petición sin restricciones, el atacante le pide que acceda a http://169.254.169.254/ (metadatos de la nube), a servicios internos o a localhost. Es una categoría propia del Top 10 desde 2023. La defensa: lista blanca de dominios y esquemas, resolver el nombre y bloquear rangos internos y de enlace local antes de conectar, y desactivar las redirecciones automáticas. Lo tratamos a fondo en nuestro artículo dedicado a SSRF.

    5.2 Improper Inventory Management

    El endpoint viejo que nadie mantiene es el que cae. /api/v1/ sigue en producción después de migrar a v2 y no recibió los últimos parches de autorización. El entorno de staging apunta a datos reales y no exige autenticación. Documentación de la API filtra endpoints internos. Hace falta un inventario vivo: qué versiones están expuestas, cuáles están deprecadas y con fecha de apagado, y qué entornos son accesibles desde fuera.

    6. Validación de esquema con OpenAPI

    Una especificación OpenAPI (antes Swagger) describe cada endpoint: parámetros, tipos, campos obligatorios, formatos, rangos. Más allá de generar documentación, sirve como contrato que se valida en tiempo de ejecución: un middleware rechaza toda petición que no encaje con el esquema antes de que llegue a la lógica de negocio.

    • Rechaza campos desconocidos (additionalProperties: false) — mitiga mass assignment de forma estructural
    • Fuerza tipos y formatos (un email es un email, un id es un entero positivo) — reduce la superficie de inyección y de errores de parseo
    • Limita longitudes y tamaños de array desde el propio contrato
    • Permite comparar lo que la API realmente expone con lo que dice exponer (útil contra el punto de inventario)
    # Fragmento de OpenAPI 3.1: el cuerpo de 'crear pedido' como contrato estricto
    requestBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            additionalProperties: false     # nada fuera de lo declarado
            required: [producto_id, cantidad]
            properties:
              producto_id: { type: integer, minimum: 1 }
              cantidad:    { type: integer, minimum: 1, maximum: 100 }
              nota:        { type: string,  maxLength: 280 }

    7. El OWASP API Security Top 10 (2023) de un vistazo

    #CategoríaEjemploDefensa principal
    API1Broken Object Level AuthorizationCambiar /invoices/1 por /invoices/2 y ver la ajenaComprobar propiedad del objeto en cada acceso
    API2Broken Authenticationalg=none, tokens sin caducidad, login sin límiteOAuth2/OIDC bien validado, límites en el login
    API3Broken Object Property Level AuthorizationExcessive data exposure + mass assignmentDTO de entrada y de salida con lista blanca
    API4Unrestricted Resource ConsumptionScraping masivo, fuerza bruta, coste en tercerosRate limiting + cuotas + límites de tamaño
    API5Broken Function Level AuthorizationEndpoint /admin protegido solo por oscuridadRol/permiso declarado por endpoint; denegar por defecto
    API6Unrestricted Access to Sensitive Business FlowsComprar todo el stock con un botDetección de automatización, límites de negocio
    API7Server-Side Request ForgeryWebhook que apunta a 169.254.169.254Lista blanca de destinos, bloquear rangos internos
    API8Security MisconfigurationCORS abierto, stack traces, cabeceras ausentesHardening por defecto, revisión de configuración
    API9Improper Inventory Management/api/v1 olvidado, staging con datos realesInventario de versiones y entornos; apagar lo viejo
    API10Unsafe Consumption of APIsConfiar a ciegas en la respuesta de un terceroValidar y sanear también lo que llega de otras APIs

    Marco legal y de uso responsable

    Todo lo descrito aquí es para auditar tu propia API o una para la que tengas autorización escrita del responsable · Probar estas técnicas —enumerar identificadores, saltarse la autorización, forzar endpoints— contra servicios de terceros sin permiso encaja en los delitos de acceso ilícito a sistemas informáticos y de descubrimiento y revelación de secretos (arts. 197 bis, 197 ter y 264 del Código Penal español) · Monta una API de pruebas propia en un entorno aislado o usa laboratorios preparados para ello (crAPI de OWASP, VAmPI) para practicar

    Conclusión

    La seguridad de una API no se resuelve con un WAF delante ni con «ya usamos HTTPS». Los fallos que más duelen aquí son de lógica: autorización que se comprueba a medias, respuestas que devuelven de más, endpoints sin límites y versiones viejas que nadie apagó. Ninguno lo detecta un escáner genérico, porque todos dependen de qué significan tus datos y quién debería poder tocarlos.

    El orden de prioridades es bastante claro: primero autorización objeto a objeto y a nivel de función en cada endpoint, luego una autenticación estándar bien validada, después rate limiting y cuotas como control de seguridad de pleno derecho, y por encima de todo un contrato OpenAPI que se valide en ejecución. Con eso cubierto, ocho de los diez puntos de OWASP dejan de aplicar a tu API.

    Referencias

    OWASP API Security Top 10 (2023) — owasp.org/API-Security · OWASP crAPI y VAmPI — APIs deliberadamente vulnerables para practicar en local · OpenAPI Specification 3.1 y herramientas de validación en ejecución (express-openapi-validator, Connexion, Zod/JSON Schema) · IETF RFC 9331 y draft de cabeceras RateLimit — el estándar en curso para RateLimit-Limit/Remaining/Reset · Nuestros artículos sobre OWASP Top 10:2025, JWT a fondo, CORS y SameSite, y SSRF, para el contexto completo

    unfantasmaenelsistema.com | Seguridad, sistemas y todo lo que no debería funcionar (pero funciona)

    Resumen de privacidad

    Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.