seguridad API · validación de entradas · JSON Schema · REST API · codificación defensiva · OWASP
Validación de Entradas para APIs Públicas Pequeñas: Una Guía Técnicamente Conservadora
Una guía práctica y opinativa sobre validación de entradas para desarrolladores independientes y equipos pequeños que construyen APIs públicas. Aprende cuándo usar JSON Schema, cómo rechazar temprano y qué errores evitar.
Publicado:
Por Qué la Validación de Entradas Importa para APIs Pequeñas
Si ejecutas una API pública con un equipo pequeño, la validación de entradas no es opcional. Es la primera línea de defensa contra ataques de inyección, corrupción de datos y abuso del servicio. El Top 10 de OWASP clasifica consistentemente las vulnerabilidades de control de acceso roto e inyección entre los riesgos más críticos, y ambos derivan de una validación inadecuada de entradas en el límite de la API.
Esta guía adopta una postura técnicamente conservadora. No recomendaremos frameworks de validación complejos ni herramientas empresariales. En cambio, nos enfocaremos en enfoques prácticos y mantenibles que equipos pequeños pueden implementar sin sacrificar seguridad.
Validar en el Límite, Rechazar Temprano
El principio más importante en validación de entradas es simple: valida cada entrada en el límite de la API antes de que llegue a la lógica de tu aplicación. No confíes en la validación del lado del cliente. No asumas que porque una solicitud proviene de tu frontend propio, es segura.
OWASP recomienda que todos los fallos de validación deben resultar en el rechazo de la entrada. Esto significa devolver una respuesta de error clara y detener el procesamiento inmediatamente. Cuanto antes rechaces entradas inválidas, menor será la superficie de ataque que expongas.
Considera un endpoint simple de registro de usuarios. Si el campo de email es requerido y debe ser un email válido, valida esto antes de consultar tu base de datos. Si la validación falla, devuelve un 400 Bad Request con un mensaje de error descriptivo. No procedas al hash de contraseña ni a la creación de usuario.
JSON Schema: Cuándo Usarlo
JSON Schema es una herramienta práctica para definir y validar la estructura de datos JSON. Actúa como un contrato entre productores y consumidores de API, especificando qué campos deben estar presentes, qué tipos de datos deben contener y qué restricciones se aplican a sus valores.
Para APIs sencillas, JSON Schema es bastante útil. Proporciona una única fuente de verdad sobre cómo se ven tus mensajes que puedes compartir con desarrolladores frontend, equipos backend y clientes externos. La documentación de Postman destaca que JSON Schema puede capturar errores temprano, hacer cumplir la consistencia entre servicios y documentar claramente los contratos de datos.
Sin embargo, JSON Schema tiene limitaciones. Expresar restricciones no triviales puede ser verboso y difícil de extender. La lógica condicional como “si el campo X se establece en 123 entonces los campos Y y Z son obligatorios” se vuelve engorrosa. Para reglas de validación complejas, las verificaciones manuales pueden ser más apropiadas.
La discusión en Hacker News sobre la practicidad de JSON Schema revela que muchos desarrolladores lo usan para APIs sencillas pero cambian a validación personalizada para lógica de negocio compleja. Un desarrollador notó que terminó cambiando de JSON Schema a esquemas Marshmallow porque necesitaban más control y menos forzar las cosas.
Validación Manual: Cuándo el Esquema se Queda Corto
No toda la validación puede expresarse en JSON Schema. Algunas restricciones requieren lógica de negocio que va más allá de la verificación de tipos. Para estos casos, la validación manual es necesaria.
OWASP recomienda usar una biblioteca o framework de validación de entradas centralizado para toda la aplicación. Si la rutina de validación estándar no puede abordar algunas entradas, usa verificaciones discretas adicionales. Siempre valida los tipos de datos esperados usando una lista blanca en lugar de una lista negra.
Por ejemplo, si necesitas validar que un número de teléfono solo se acepta en endpoints de búsqueda pero no en operaciones POST o PATCH, JSON Schema no puede expresar esta restricción. Necesitarías validación manual en tus manejadores de rutas.
De manera similar, si el campo Y es válido solo en búsquedas y el campo Z es válido solo en PUT/PATCH pero no en POST, necesitas lógica personalizada. Aquí es donde brilla la validación manual.
Evitando Errores Comunes
Denegación de Servicio por Expresiones Regulares
Las expresiones regulares pueden ser poderosas pero también peligrosas. Patrones regex complejos pueden llevar a ataques de denegación de servicio por regex (ReDoS), donde una entrada especialmente diseñada hace que el motor regex tome tiempo exponencial. Para APIs pequeñas, mantén los patrones regex simples y pruébalos contra entradas maliciosas.
Coerción de Tipos Implícita
Muchos lenguajes de programación realizan coerción de tipos implícita, lo que puede llevar a comportamientos inesperados. Una cadena “123” podría convertirse automáticamente a entero, o “true” podría convertirse a booleano. Esto puede eludir verificaciones de validación e introducir vulnerabilidades de seguridad.
Siempre valida los tipos explícitamente. No confíes en la coerción implícita. Si un campo debe ser un entero, asegúrate de que lo sea antes de proceder.
Validación de Conjuntos de Caracteres
OWASP recomienda especificar conjuntos de caracteres como UTF-8 para todas las fuentes de entrada. Si el sistema soporta conjuntos de caracteres UTF-8 extendidos, valida después de completar la decodificación UTF-8. Verifica que los valores de encabezado de protocolo tanto en solicitudes como en respuestas contengan solo caracteres ASCII.
Validación de Cargas de Archivos
Si tu API acepta cargas de archivos, no pases datos proporcionados por el usuario directamente a ninguna función de inclusión dinámica. Limita el tipo de archivos que se pueden cargar solo a aquellos necesarios para propósitos comerciales. Valida los archivos cargados verificando los encabezados de archivo en lugar de las extensiones, ya que las extensiones pueden spoofearse fácilmente.
Pasos de Implementación Práctica
-
Identifica todas las fuentes de datos y clasifícalas como confiables y no confiables. Los datos proporcionados por el cliente son no confiables hasta que se demuestre lo contrario.
-
Valida todos los datos de entrada de fuentes no confiables. Esto incluye parámetros de consulta, parámetros de ruta, encabezados y cuerpos de solicitud.
-
Codifica la entrada a un conjunto de caracteres común antes de validar. Esto previene ataques basados en codificación.
-
Usa listas blancas, no listas negras. Especifica lo que se permite en lugar de lo que se prohíbe. Las listas negras pueden eludirse con entradas inesperadas.
-
Valida el rango y la longitud de los datos. Verifica que los valores numéricos estén dentro de rangos esperados y que las cadenas no excedan longitudes máximas.
-
Registra los fallos de validación. Esto te ayuda a detectar intentos de ataque y ajustar tus reglas de validación.
-
Prueba tus validadores. Asegúrate de que tu lógica de validación rechace correctamente las entradas maliciosas y acepte las válidas.
FAQ
P: ¿Debería validar también en el lado del cliente?
La validación del lado del cliente es importante para la experiencia de usuario, proporcionando retroalimentación inmediata. Sin embargo, nunca debe ser tu única capa de validación. Siempre valida también en el lado del servidor. La validación del lado del cliente puede eludirse fácilmente.
P: ¿Cómo manejo objetos anidados en JSON Schema?
JSON Schema soporta objetos anidados definiendo esquemas dentro del campo properties. Puedes crear reglas de validación profundamente anidadas referenciando otros esquemas o definiéndolos en línea.
P: ¿Qué pasa con los errores de validación en las respuestas?
Los errores de validación deben ser claros y accionables. Incluye el nombre del campo, el tipo o formato esperado, y una breve descripción de qué salió mal. Evita exponer detalles de implementación interna.
P: ¿Puedo usar JSON Schema tanto para solicitudes como para respuestas?
Sí. JSON Schema puede validar tanto solicitudes entrantes como respuestas salientes. Esto asegura consistencia en toda tu API y ayuda a capturar errores temprano.
P: ¿Cómo manejo la validación condicional?
Para validación condicional que JSON Schema no puede expresar, usa validación manual en tus manejadores de rutas. Combina la validación de esquemas para verificaciones estructurales con lógica personalizada para reglas de negocio.
Fuentes
- OWASP Input Validation Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html
- OWASP Validate All Inputs Developer Guide: https://devguide.owasp.org/en/04-design/02-web-app-checklist/05-validate-inputs
- OWASP REST Security Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
- Postman JSON Schema Guide: https://blog.postman.com/json-schema-data-types
- Hacker News JSON Schema Discussion: https://news.ycombinator.com/item?id=16406855
- PactFlow Contract Testing with JSON Schemas: https://pactflow.io/blog/contract-testing-using-json-schemas-and-open-api-part-1
- APIs You Won’t Hate JSON Schema Article: https://medium.com/apis-you-wont-hate/the-many-amazing-uses-of-json-schema-client-side-validation-c78a11fbde45
