Una API es una puerta de entrada directa a la lógica y a los datos de un sistema. A diferencia de una interfaz web, no tiene pantallas que limiten lo que el usuario puede intentar: cualquiera que conozca la dirección puede enviar cualquier solicitud. Por eso los controles deben estar en el servidor y no en la aplicación que la consume.
Como referencia general, el proyecto OWASP API Security Top 10 recopila las categorías de riesgo más frecuentes en APIs. Esta guía se centra en los controles prácticos que cubren buena parte de ellas.
1. Autenticación: saber quién llama
| Mecanismo | Uso típico | Precauciones |
|---|---|---|
| Clave de API | Integraciones servidor a servidor simples. | Nunca en aplicaciones web o móviles; rotación periódica; una clave por cliente. |
| OAuth 2.0 (credenciales de cliente) | Servicios que se comunican entre sí. | Tokens de vida corta y con alcances limitados. |
| Tokens de usuario (OAuth 2.0 / OpenID Connect) | Aplicaciones donde una persona inicia sesión. | Expiración corta, renovación controlada y revocación. |
| TLS mutuo | Integraciones entre organizaciones con alta exigencia. | Gestión de certificados y su renovación. |
Cualquier clave incluida en el código de una aplicación web o en el instalable de una app móvil puede extraerse. Si una app necesita llamar a un servicio que requiere una clave, la llamada debe pasar por tu servidor, que es quien guarda la clave.
2. Autorización por objeto: el fallo más común
Estar autenticado no significa poder acceder a todo. El problema más frecuente en APIs ocurre cuando el servidor verifica que el usuario inició sesión, pero no que el recurso solicitado le pertenece. Si un cliente consulta GET /pedidos/1042 y luego prueba /pedidos/1043, la API no debe devolverle el pedido de otra persona.
// Incorrecto: solo verifica que haya sesión
obtenerPedido(usuario, idPedido):
devolver buscarPedido(idPedido)
// Correcto: el filtro por propietario es parte de la consulta
obtenerPedido(usuario, idPedido):
pedido = buscarPedido(id = idPedido, cliente = usuario.clienteId)
si pedido es nulo: responder 404
devolver pedido
Responder 404 en lugar de 403 evita confirmar que el recurso existe. Usar identificadores no secuenciales ayuda, pero no reemplaza la verificación: la protección real es el control de propiedad en cada consulta.
3. Autorización por función y por campo
- Por función: los endpoints administrativos (cambiar precios, ver todos los clientes) deben verificar el rol del usuario en el servidor, aunque la app nunca muestre esos botones a usuarios comunes.
- Por campo al escribir: si la API copia todos los campos recibidos al modelo, un usuario podría enviar
"rol": "admin"o"precio": 0. Acepta explícitamente solo los campos permitidos. - Por campo al leer: devuelve solo lo que el cliente necesita. Enviar el objeto completo de la base de datos y «ocultar» campos en la interfaz expone datos a quien inspeccione la respuesta.
4. Validación de entradas
Toda entrada se valida en el servidor, aunque la aplicación cliente ya la haya validado: tipos de dato, formatos, longitudes máximas, rangos y valores permitidos. Definir esquemas de solicitud (por ejemplo, con OpenAPI o JSON Schema) permite validar de forma consistente y documentar al mismo tiempo. Las consultas a la base de datos deben usar parámetros, nunca concatenar texto recibido.
5. Límites de uso y de recursos
- Límite de solicitudes por cliente o por IP, con respuesta 429 cuando se supera.
- Paginación obligatoria con un tamaño máximo de página: un endpoint que devuelve «todos los registros» es un riesgo de rendimiento y de exposición de datos.
- Tamaño máximo de solicitudes y archivos.
- Protección específica en endpoints sensibles: inicio de sesión, recuperación de contraseña y envío de códigos, que son objetivo de ataques automatizados.
6. Transporte y secretos
- TLS en todas las comunicaciones, también entre servicios internos cuando atraviesan redes compartidas.
- Secretos (claves, contraseñas de bases de datos, tokens de terceros) fuera del código fuente: en variables de entorno protegidas o en un gestor de secretos.
- Rotación posible sin cambiar código, y rotación inmediata si un secreto se expone.
- Revisión de los repositorios para detectar secretos publicados por error, incluido el historial.
7. Webhooks entrantes
Un endpoint que recibe webhooks es una API pública que cualquiera puede llamar. Si el emisor firma sus notificaciones, verifica la firma con el secreto compartido antes de procesar nada, usando una comparación de tiempo constante. Si la notificación incluye una marca de tiempo, rechaza las que sean demasiado antiguas para evitar que se reenvíen notificaciones capturadas. Aplicado a pagos, lo explicamos en webhooks de pago.
8. CORS no es un mecanismo de seguridad del servidor
CORS indica a los navegadores qué orígenes pueden leer las respuestas de tu API. Es útil, pero no impide que un script, una app o una herramienta de línea de comandos llamen a la API directamente. La autenticación y la autorización siguen siendo imprescindibles.
9. Registro, monitoreo e inventario
Registra los intentos de autenticación fallidos, los accesos denegados y los picos inusuales de solicitudes, sin incluir credenciales ni datos sensibles. Mantén además un inventario de qué endpoints y versiones están publicados: las versiones antiguas olvidadas, sin los controles actuales, son una fuente frecuente de incidentes.
Lista de verificación
- Ningún secreto está incluido en aplicaciones web o móviles.
- Cada consulta verifica la propiedad del recurso solicitado.
- Los endpoints administrativos verifican el rol en el servidor.
- Solo se aceptan y devuelven los campos necesarios.
- Todas las entradas se validan en el servidor con esquemas.
- Hay límites de solicitudes, paginación y tamaño.
- Los secretos están fuera del código y pueden rotarse.
- Los webhooks entrantes se verifican.
- Existe inventario de endpoints y versiones.
Preguntas frecuentes
¿Basta con usar HTTPS?
No. HTTPS protege los datos en tránsito, pero no decide quién puede acceder a qué. Autenticación, autorización y validación siguen siendo necesarias.
¿Las APIs internas también necesitan estos controles?
Sí, en una medida proporcional al riesgo. Una red interna no es garantía de confianza: un equipo comprometido o un servicio mal configurado pueden alcanzar esas APIs.
¿Con qué frecuencia debo revisar la seguridad de una API?
Al diseñar cada endpoint nuevo y de forma periódica, además de cada vez que se actualizan dependencias o se agrega un nuevo consumidor.