La lista de verificación de seguridad de API

Sat Aug 22 2026

La lista de verificación de seguridad de API

Un JWT válido demuestra quién es el emisor de la llamada. No demuestra que pueda leer el pedido 12345. El fallo que normalmente priorizaría aparece después de la autenticación: nunca se aplicaron la propiedad, los permisos de campos, los límites de recursos o las reglas de negocio.

Pero esta lista de verificación de buenas prácticas de seguridad de API está pensada para revisiones de producción en 2026. Sigue una solicitud desde la identidad, pasando por los permisos, el uso de recursos, el manejo de entradas, el transporte, la detección, los secretos y la verificación. Copia las comprobaciones en tickets de ingeniería o en pruebas de aprobado/fallido.

Y esta lista de verificación es más sólida en autorización y manejo de solicitudes. No sustituye al modelado de amenazas de un sistema de pagos regulado ni a una revisión de la implementación de tu proveedor de identidad.

En este artículo

No existe una edición OWASP API Security Top 10 2026

Y el OWASP API Security Project incluye API Security Top 10:2023, publicada el 5 de junio de 2023, como la edición estable actual. Llamar a esto “la lista OWASP 2026” sería inexacto; 2026 es la fecha de revisión, no el número de edición.

Por tanto, la taxonomía cubre API1 Broken Object Level Authorization, API3 Broken Object Property Level Authorization, API4 Unrestricted Resource Consumption, API5 Broken Function Level Authorization, API6 Sensitive Business Flows, API7 SSRF, API9 Improper Inventory Management y API10 Unsafe Consumption of APIs. OWASP también cubre la autenticación deficiente y la configuración incorrecta de seguridad.

OWASP proporciona la taxonomía de riesgos. Mi uso práctico de ella es más sencillo: asignar cada ruta a un propietario, un predicado de autorización y una prueba. La guía de pruebas de penetración de REST API de Blackhawk cubre las pruebas prácticas que siguen a la revisión del diseño.

[IMAGE PLACEHOLDER: OWASP API Security Top 10 (2023) visual, clearly labelled “current stable edition as of 22 August 2026”; source/link to OWASP API Security Top 10]

La autenticación depende del cliente y del límite de confianza

Empieza separando lo que hacen OAuth, JWT y las API keys. OAuth 2.0 es un marco de autorización, JWT es un formato de token y una API key es una credencial. Una API key normalmente identifica una aplicación o integración; por sí sola no contiene permisos a nivel de objeto.

Cliente o integraciónPunto de partida adecuadoComprobaciones verificables
Usuario de navegador o móvilAuthorization Code con PKCEValida la URI de redirección, el intercambio del código de autorización, el verificador PKCE, la audiencia del token y los scopes
Cliente de máquina dentro de un límite de confianzaOAuth 2.0 Client CredentialsAsigna scopes reducidos a cada cliente; verifica la autenticación del cliente y revoca las credenciales durante la baja
Integración entre organizaciones o reguladamTLS u OAuth con mTLSValida el certificado del cliente, la cadena de certificados, la caducidad y la vinculación del certificado o token
Tarea programada o webhook de baja sensibilidadAPI keyLimita el alcance de la key, rótala, revócala y aplica límites por endpoint y tenant
Cliente público que necesita tokens vinculados al emisorDPoP cuando tu proveedor y tus bibliotecas lo admitanVerifica la firma de la prueba, el método HTTP, la URL de la solicitud, el nonce o el comportamiento de replay y la vinculación del token

Y utiliza una biblioteca OAuth o un servicio de identidad mantenido. La comparación de Skycloak es útil para elegir entre tipos de clientes, pero tu API sigue siendo responsable de la decisión de seguridad final.

OAuth proporciona a un cliente un token de acceso; tu API todavía decide si ese token puede realizar esta operación sobre este objeto. Tu servidor debe tomar esas decisiones.

Para cada token de acceso bearer o JWT, comprueba su firma contra un conjunto de claves de confianza. Verifica el algoritmo permitido, el emisor, la audiencia, la caducidad y los claims requeridos. Nunca incluyas secretos de cliente en bundles de navegador ni en aplicaciones móviles. La guía de seguridad de Node.js y la guía de seguridad de Django cubren el manejo específico de tokens y middleware de cada framework.

La validación de JWT todavía necesita una estrategia de revocación

Para GET /profile o una operación de lectura ordinaria, la validación local suele ser práctica. Pero la recuperación de cuentas y la autorización de pagos pueden necesitar una llamada de introspección para comprobar el estado actual del token.

MétodoVentajaCoste
Validación local con JWKSRápida, capaz de funcionar offline e independiente de una llamada al servidor de autorización durante la solicitudUn token revocado puede seguir utilizándose hasta que caduque
IntrospecciónRefleja el estado actual del token y detecta la revocación rápidamenteAñade latencia y una dependencia del servidor de autorización

Usa la validación local cuando la ventana de caducidad encaje con tu modelo de riesgo. Considera la introspección para pagos y recuperación de cuentas. Úsala también cuando los cambios de permisos u otra vía hagan crítica la revocación. Acortar la duración reduce la exposición; nunca sustituye la autorización de objetos ni un control de revocación.

Un token de acceso de 15 minutos y un token de actualización de siete días son puntos de partida concretos de orientación secundaria de profesionales; OWASP no los exige. No puedo elegir tu ventana de caducidad sin conocer la combinación de clientes, las necesidades de revocación y la tolerancia a incidentes.

Fija los algoritmos aceptados, rota las claves de firma y rechaza alg:none, los algoritmos no aprobados, el emisor incorrecto, la audiencia incorrecta y los tokens caducados. Prueba directamente esos fallos.

Un token válido no autoriza un objeto

Toma una API de pedidos multi-tenant. Este handler autentica al emisor de la llamada y después confía en el identificador proporcionado por él:

app.get("/api/orders/:id", auth, async (req, res) => {
  const order = await db.orders.findById(req.params.id);
  return res.json(order);
});

Una búsqueda más segura incorpora el predicado de autorización en la operación de acceso a datos:

app.get("/api/orders/:id", auth, async (req, res) => {
  const order = await db.orders.findOne({
    id: req.params.id,
    tenantId: req.user.tenantId,
    ownerId: req.user.id
  });

  if (!order) {
    return res.sendStatus(404);
  }

  return res.json(order);
});

Este ejemplo supone que solo el propietario puede ver un pedido. Si varios usuarios de un tenant pueden ver un pedido, sustituye ownerId por el predicado de políticas real: pertenencia al tenant, relación con la cuenta, rol u otra regla explícita.

OWASP API1 expresa claramente el requisito: “Los controles de autorización a nivel de objeto deben considerarse en cada función que acceda a una fuente de datos utilizando un ID del usuario”. Aplica esa comprobación a lecturas, actualizaciones, eliminaciones, recursos anidados, exportaciones y acciones en segundo plano.

La respuesta 404 es una opción habitual para objetos fuera del ámbito visible del emisor de la llamada porque evita revelar si el objeto existe. Yo modelaría el acceso del personal como una política independiente y explícita, en lugar de eliminar silenciosamente la condición de propiedad para todo el mundo.

BOLA, o Broken Object Level Authorization, es el término de OWASP. Los equipos todavía suelen llamar IDOR a los fallos de sustitución de identificadores. Para prevenir BOLA e IDOR, prueba con dos usuarios ordinarios, no con un administrador:

  • Sustituye identificadores. Cambia IDs numéricos, UUID, identificadores anidados e identificadores de tenant.
  • Cubre todos los métodos. Prueba las rutas GET, PATCH, DELETE y de exportación.
  • Prueba el límite. Usa usuarios del mismo tenant y de tenants diferentes.
  • Comprueba la inferencia. Compara códigos de estado, tamaños de respuesta y tiempos para objetos inaccesibles.

Un usuario con pocos privilegios debe fallar en cada intento de leer, modificar, eliminar, exportar o inferir el pedido de otro tenant. Usa la guía de Node.js para los detalles de implementación de Express; ejecuta el procedimiento completo mediante tu proceso de pruebas de seguridad.

Los permisos a nivel de campo bloquean la asignación masiva

Extender req.body permite que un emisor de la llamada intente cambiar status, ownerId o paymentState:

await db.orders.update(req.params.id, {
  ...req.body
});

Un campo role o isVerified editable crea una escalada de privilegios. Devolver campos internos crea una exposición excesiva de datos. OWASP API3:2023 agrupa ambas preocupaciones anteriores bajo Broken Object Property Level Authorization.

Valida primero el body y después construye una lista permitida:

const body = updateOrderSchema.parse(req.body);

const updates = {
  shippingAddress: body.shippingAddress,
  deliveryInstructions: body.deliveryInstructions
};

await db.orders.updateOwned(req.params.id, req.user.id, updates);

El paso del esquema se muestra aquí como una ilustración de permisos; todavía necesita tipos de campos, longitudes y reglas para valores anidados.

Mantén los cambios de flujo controlados por el servidor separados de las actualizaciones ordinarias. Un cliente puede editar una dirección de envío, mientras que solo un flujo de trabajo autorizado puede cambiar el estado del pago. Devuelve DTO de respuesta en lugar de objetos de la base de datos, para que los campos de auditoría, los metadatos del tenant, los datos de pago y las marcas administrativas permanezcan internos.

Las comprobaciones de objetos y propiedades dejan un tercer límite: si este emisor de la llamada puede invocar la función en absoluto. API5 cubre esa decisión a nivel de función, especialmente para las rutas administrativas. Prueba intentos de llamar a endpoints de administración con tokens de usuarios ordinarios.

Haz que las solicitudes abusivas sean costosas de enviar y baratas de rechazar

La limitación de tasa no es una configuración decorativa del gateway. El inicio de sesión, el restablecimiento de contraseñas, la búsqueda, la exportación y la paginación necesitan límites diferentes. Las acciones de negocio costosas también los necesitan. Las cuotas por tenant importan tanto como los límites por IP.

Esta es una política inicial lista para convertir en ticket:

  • Inicio de sesión: cinco intentos por cada 15 minutos y por IP, con un control basado en la identidad cuando corresponda.
  • Restablecimiento de contraseña: límites más estrictos que para las lecturas ordinarias, con alertas de abuso.
  • Búsqueda y exportación: límites de endpoint independientes, conjuntos de resultados acotados y cuotas por tenant.
  • Paginación: aplica un limit máximo; rechaza solicitudes de listas sin límites.
  • Flujos de negocio: limita las acciones similares al checkout por identidad, tenant y estado de negocio; los límites por IP por sí solos son insuficientes.
  • Comportamiento ante fallos: devuelve 429 Too Many Requests y Retry-After; aplica una alternativa conservadora si el estado del limitador no está disponible.

El ejemplo de cinco intentos por cada 15 minutos y por IP procede de la orientación de profesionales de Quantlab. No es un valor predeterminado de OWASP. Las redes de oficinas compartidas y los operadores móviles pueden situar a muchos usuarios detrás de una misma dirección, así que mide los falsos positivos antes de adoptarlo.

Para la API de pedidos, prueba valores sobredimensionados de GET /api/orders?limit=..., exportaciones repetidas, búsquedas costosas y solicitudes repetidas similares al checkout, mientras las lecturas ordinarias permanecen por debajo de su límite. Los límites deben acotar el ancho de banda, la CPU, la memoria, el almacenamiento y la capacidad de negocio.

Ejemplo de respuesta únicamente; utiliza el formato compatible con tu gateway y tus clientes:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
RateLimit-Limit: 60
RateLimit-Remaining: 0

Valida en el límite y rechaza las entradas inseguras

Valida los valores de ruta, consulta, header y body antes de que la lógica de negocio o la persistencia los procesen. Los esquemas estrictos como Zod, JSON Schema y Pydantic deberían exigir tipos y campos obligatorios. También deberían exigir longitudes, rangos, formatos, valores enumerados y anidamientos permitidos.

Usa esta lista de verificación de límites:

  • Esquema: rechaza valores fuera del contrato; normaliza solo cuando el contrato defina la normalización.
  • Reglas de negocio: exige cantidades positivas y acotadas; un pedido enviado no debe volver a pending.
  • Contenido: verifica Content-Type, el tamaño del payload y las codificaciones aceptadas.
  • Base de datos: utiliza sentencias preparadas y consultas parametrizadas. La guía de inyección SQL de Blackhawk cubre la construcción de consultas y las pruebas específicas de inyección.
  • URL: si la API obtiene un recurso remoto, permite únicamente destinos incluidos en una lista autorizada. Bloquea los rangos internos y de metadatos de la nube. Valida cada destino al que el cliente HTTP vaya a realizar realmente una solicitud.
  • Datos de terceros: analiza las respuestas de los proveedores contra un esquema, aplica límites de tamaño y mantén sus campos alejados de las rutas de actualización privilegiadas.

OWASP API7 cubre SSRF, mientras que API10 cubre el consumo inseguro de API externas. Una cadena que parece una URL sigue siendo una entrada del usuario.

Las llamadas internas también necesitan TLS

Aplica HTTPS y TLS a los endpoints públicos y a las llamadas entre servicios internos. Una ruta interna todavía puede alcanzarse después de un error de enrutamiento, de la intrusión en una carga de trabajo o de una configuración incorrecta del proxy. Exige una identidad de servicio autenticada siempre que un servicio posterior tome decisiones de autorización.

Comprueba tres cosas:

  1. El HTTP en texto plano se rechaza o redirige según tu política de despliegue.
  2. Los clientes salientes verifican los certificados y rechazan identidades inválidas, caducadas o inesperadas.
  3. Las pruebas de webhook rechazan firmas ausentes o inválidas, marcas de tiempo obsoletas e IDs de eventos reutilizados cuando el proveedor proporcione controles contra replay.

Utiliza la configuración segura de TLS compatible actualmente con tu plataforma en lugar de copiar una lista estática de cifrados en una lista de verificación. Mantén los tokens bearer fuera de las URL, los datos de analítica y los registros.

Los registros deberían explicar la denegación

La mayoría de las revisiones de API invierten demasiado en la validación de tokens porque es fácil de demostrar. El registro recibe el trato opuesto: un ticket impreciso de “añadir observabilidad” y ninguna evidencia de que un investigador pudiera reconstruir un ataque.

Para una denegación de autorización, registra el identificador menos sensible que todavía permita investigar, junto con los controles de retención y acceso. Un esquema ilustrativo debería contener:

{
  "event": "authorization_denied",
  "requestId": "<request identifier>",
  "actor": "<user or service identifier>",
  "tenant": "<tenant identifier>",
  "requestPath": "/api/orders/:id",
  "endpoint": "GET /api/orders/:id",
  "object": "<order reference>",
  "action": "read",
  "policy": "order_owner_or_tenant_member",
  "reason": "object_outside_actor_scope",
  "outcome": "denied",
  "timestamp": "<UTC timestamp>",
  "clientContext": "<redacted network or client context>"
}

Registra los fallos de autenticación y las denegaciones de autorización. Registra las acciones de alto valor, las exportaciones, los eventos de limitación de tasa y el acceso a endpoints obsoletos o de depuración. Nunca registres contraseñas, tokens de acceso ni payloads sensibles.

Crea alertas para respuestas 401 y 403 repetidas, patrones de sondeo de identificadores, exportaciones inusuales y aumentos repentinos de la limitación de tasa. Mantén un inventario de endpoints y versiones. Después de un cambio de autenticación o acceso a datos, insistiría en ejecutar una nueva prueba de penetración en lugar de confiar en el informe anterior.

Los secretos son credenciales, así que rótalos cuando sea posible que se hayan expuesto

Almacena las API keys, contraseñas de bases de datos, claves de firma y credenciales de servicio en un almacén de secretos gestionado. Limita cada secreto a sus permisos mínimos y a su entorno. Nunca incluyas secretos en bundles de navegador ni en aplicaciones móviles; los clientes pueden extraerlos.

Cuando una credencial pueda haberse filtrado:

  1. Identifica cada sistema que la utiliza.
  2. Revócala o desactívala inmediatamente.
  3. Emite un reemplazo con un alcance más reducido.
  4. Elimínala del código fuente, historial, artefactos de compilación, registros y respuestas de error.
  5. Revisa los registros de acceso para detectar usos indebidos.
  6. Rota las credenciales relacionadas si compartieron la misma exposición.

Una key filtrada es un incidente, incluso cuando no tengas pruebas de que se haya utilizado. Prefiere tokens de corta duración cuando la integración los admita y rótalos tanto según un calendario como ante cualquier sospecha.

Ejecuta la lista de verificación como pruebas, no como un documento de políticas

Copia estas filas en tu ticket de lanzamiento. Cada condición de aprobado nombra la evidencia que un revisor puede inspeccionar.

ComprobaciónCondición de aprobadoEvidencia
Inventario de endpointsSe conocen todos los hosts, rutas, versiones, endpoints de depuración y versiones obsoletasInventario de rutas versionado con propietario y fecha de retirada
AutenticaciónEl mecanismo se ajusta al cliente; se validan el emisor, la audiencia, la caducidad, la firma, el algoritmo y los claimsPruebas de middleware que muestran tokens aceptados y rechazados
Autorización de objetosLos cambios de identificadores entre usuarios y tenants fallan para lecturas, actualizaciones, eliminaciones, recursos anidados y exportacionesMatriz de pruebas con usuarios con pocos privilegios y aserciones sobre respuestas
Autorización de propiedadesLos campos editables están incluidos en una lista permitida; los campos sensibles no pueden asignarse masivamentePruebas de esquema, DTO y mutación negativa de campos
Autorización de funcionesLas funciones administrativas y ordinarias aplican políticas separadasPruebas de roles o políticas para cada ruta privilegiada
Controles de recursosLa paginación, los payloads, las consultas, las exportaciones, los flujos de negocio y el uso por tenant están acotadosPruebas de 429, configuración de cuotas y pruebas de valores máximos
ValidaciónSe validan los esquemas, tipos de contenido, URL, entradas SQL y respuestas de tercerosResultados de pruebas de límites y revisión de consultas preparadas
TransporteTLS se aplica en cada salto y se verifican las firmas de webhookPruebas de texto plano, certificados, firmas, marcas de tiempo y replay
DetecciónLos eventos de seguridad incluyen emisor, tenant, ruta, acción, resultado, motivo y hora sin secretosMuestras de eventos redactadas y reglas de alerta
SecretosLas credenciales tienen alcance limitado, se almacenan de forma segura, se rotan y pueden revocarseInventario de secretos, registro de rotación y análisis del repositorio
Repetición de pruebasLos cambios de autenticación y acceso a datos activan pruebas de seguridad antes del lanzamientoEjecución de pruebas vinculada o excepción aprobada

Para la API de pedidos, crea a Alice y Bob en el tenant A. Coloca a Carol en el tenant B. Prueba todas las combinaciones de IDs de pedidos y contexto de tenant. Intenta modificar campos y utilizar una paginación sobredimensionada. Repite exportaciones e intenta abusar de los flujos de negocio. El OWASP API Security Project también incluye crAPI, un proyecto de API intencionadamente vulnerable, para practicar de forma segura.

Si no hay una prueba de denegación entre tenants, no hay lanzamiento.