Tema 13

13. Seguridad en subida de archivos, deserialización y lógica de negocio

No todos los riesgos web aparecen por inyecciones o sesiones. Algunas vulnerabilidades surgen cuando la aplicación acepta archivos complejos, reconstruye objetos desde datos externos o permite abusar de procesos de negocio que, técnicamente, parecen válidos. Estas fallas suelen ser menos evidentes y, por eso mismo, muy peligrosas.

Objetivo Detectar riesgos donde el dato y el flujo parecen legítimos
Enfoque Archivos, objetos y abuso funcional
Resultado Diseñar controles más allá de la validación básica

13.1 Introducción

Hay vulnerabilidades que no se explican del todo con categorías clásicas como SQL Injection o XSS. Algunas aparecen cuando la aplicación confía en estructuras complejas que recibe del usuario, cuando acepta archivos sin procesarlos de forma segura o cuando permite ejecutar un flujo de negocio sin considerar cómo podría abusarse.

Estas áreas son especialmente delicadas porque muchas veces la aplicación “hace lo que se le pidió”, pero el problema es precisamente que esa petición nunca debería haber sido aceptada en ese contexto.

En este tema veremos tres bloques relacionados: subida de archivos, deserialización y lógica de negocio.

13.2 Subida de archivos: por qué es una superficie crítica

Permitir que los usuarios suban archivos parece una función simple y útil: comprobantes, imágenes, documentos, planillas, PDFs, currículums, reportes o anexos. Pero un archivo no es solo un contenido inofensivo. Puede ser enorme, malformado, ejecutable, ambiguo o diseñado específicamente para activar fallas al ser procesado.

La subida de archivos es delicada porque introduce un objeto complejo controlado por el usuario dentro del sistema. Eso puede afectar almacenamiento, procesamiento, interpretación y exposición posterior del archivo.

13.3 Riesgos comunes en subida de archivos

  • Carga de contenido ejecutable o activo.
  • Falsificación de extensión o tipo de archivo.
  • Archivos extremadamente grandes para degradar servicio.
  • Metadatos maliciosos o sensibles.
  • Archivos servidos luego desde ubicaciones inseguras.
  • Procesamiento automático vulnerable del archivo subido.
El error más común es pensar que el archivo “es lo que dice ser” porque su nombre termina en cierta extensión o porque el navegador envió un tipo aparente.

13.4 Extensión, tipo real y validación

Confiar solo en la extensión del archivo es insuficiente. Un atacante puede renombrar un archivo peligroso para que parezca una imagen, un PDF o un documento. También puede manipular el tipo de contenido reportado en la solicitud.

Por eso una validación razonable suele incluir varias capas:

  • Restricción de tipos permitidos según el negocio.
  • Control de tamaño máximo.
  • Revisión del tipo real o estructura esperada.
  • Rechazo de formatos innecesarios o especialmente riesgosos.

13.5 Almacenamiento seguro del archivo

No basta con aceptar o rechazar el archivo. También importa dónde y cómo se almacena. Un error frecuente es guardar archivos subidos en rutas directamente accesibles desde el servidor web, con su nombre original y sin control adicional.

Buenas prácticas comunes incluyen:

  • Renombrar el archivo del lado servidor.
  • Separar almacenamiento de la ruta pública cuando sea posible.
  • No permitir ejecución o interpretación como código.
  • Controlar quién puede descargar o visualizar el recurso luego.

13.6 Procesamiento de archivos y riesgo ampliado

Muchas aplicaciones no solo guardan archivos; también los procesan: generan miniaturas, extraen texto, convierten formatos, leen metadatos o los analizan automáticamente. Cada una de esas operaciones introduce riesgo adicional si las herramientas o bibliotecas usadas no están bien elegidas o aisladas.

El archivo subido puede convertirse entonces en entrada para otros componentes internos, ampliando la superficie de ataque.

13.7 Metadatos y exposición inesperada

Un archivo puede contener más información de la que parece a simple vista: autor, ubicación, herramienta de edición, historial, comentarios o datos internos. Si la aplicación publica o reutiliza esos archivos sin tratamiento adecuado, puede exponer información innecesaria.

La seguridad de archivos no consiste solo en evitar ejecución de contenido peligroso, sino también en revisar qué información secundaria viaja con ellos.

13.8 Deserialización: idea general

Serializar es convertir una estructura de datos u objeto a un formato transportable o almacenable. Deserializar es reconstruirlo. Este proceso es útil y común en aplicaciones, APIs, colas, sesiones, cachés o integraciones.

El problema aparece cuando la aplicación deserializa datos provenientes de una fuente no confiable o insuficientemente validada. En ese caso, puede reconstruir estructuras peligrosas, inesperadas o manipuladas por el atacante.

13.9 Por qué la deserialización puede ser peligrosa

La deserialización insegura es peligrosa porque transforma datos externos en estructuras internas con significado para la aplicación o para bibliotecas del entorno. Si esa reconstrucción activa lógica no prevista, el impacto puede incluir corrupción de estado, acceso indebido, abuso del flujo o incluso ejecución más grave según la tecnología involucrada.

El problema central no es el formato en sí, sino el acto de confiar en que un objeto reconstruido desde el exterior puede tratarse como si fuera legítimo.

13.10 Señales de riesgo en deserialización

  • La aplicación acepta objetos complejos enviados por el cliente sin esquema estricto.
  • Se reconstruyen tipos internos a partir de datos externos.
  • Se confía en sesiones o tokens que contienen estructuras manipulables.
  • Se usan bibliotecas de serialización con historial de problemas o defaults inseguros.
  • Se procesan datos firmados o empaquetados sin verificación suficiente.

13.11 Defensas frente a deserialización insegura

Algunas defensas útiles son:

  • Evitar deserializar datos de fuentes no confiables cuando no sea imprescindible.
  • Usar formatos simples y esquemas estrictos.
  • Firmar o validar adecuadamente estructuras que el cliente devuelve.
  • No reconstruir tipos arbitrarios definidos desde el exterior.
  • Actualizar y revisar bibliotecas involucradas en el proceso.

En seguridad, cuanto menos “inteligencia” se reconstruya automáticamente desde el cliente, menor será el riesgo.

13.12 Lógica de negocio: un tipo distinto de vulnerabilidad

Las fallas de lógica de negocio aparecen cuando el sistema permite acciones técnicamente válidas, pero incompatibles con la intención real del proceso. A diferencia de una inyección o un XSS, aquí muchas veces no hay caracteres especiales ni payloads extraños. El atacante usa la funcionalidad normal del sistema, pero de una forma no prevista.

Por eso estas fallas son especialmente difíciles de detectar con validaciones genéricas o herramientas automáticas.

13.13 Ejemplos típicos de abuso de lógica

  • Aplicar varias veces un descuento pensado para un único uso.
  • Modificar cantidades, precios o combinaciones de productos fuera del flujo esperado.
  • Realizar operaciones en un orden no previsto por el negocio.
  • Usar una acción permitida en un momento o estado incorrecto.
  • Omitir pasos intermedios que la interfaz daba por supuestos.

En todos estos casos, el sistema puede estar respondiendo “correctamente” desde la perspectiva técnica, pero incorrectamente desde la lógica de negocio.

13.14 Lógica de negocio y confianza excesiva en el cliente

Muchas fallas de lógica aparecen cuando la aplicación delega demasiado en el frontend. Si el cliente calcula descuentos, estados, totales o restricciones y el backend solo los acepta, el atacante puede manipular esos valores.

La regla de seguridad sigue siendo la misma: las decisiones importantes deben recalcularse o verificarse del lado servidor.

13.15 Secuencia, estado y procesos

Una aplicación segura no solo valida datos individuales. También valida el estado del proceso. Si una acción solo tiene sentido después de otra, o si un recurso cambia de comportamiento según su estado, el backend debe comprobarlo explícitamente.

Ejemplos:

  • Un pedido no debería cancelarse si ya fue enviado.
  • Un cupón no debería reutilizarse si el negocio lo define como único.
  • Una aprobación no debería poder ejecutarse si faltan pasos previos.

13.16 Cómo pensar pruebas de lógica de negocio

Las pruebas clásicas de validación suelen preguntar si un campo tiene el formato correcto. Las pruebas de lógica de negocio deben ir más allá:

  • ¿Qué pasa si repito la acción muchas veces?
  • ¿Qué pasa si cambio el orden del flujo?
  • ¿Qué pasa si uso un recurso en otro estado?
  • ¿Qué pasa si combino funciones que el negocio pensó por separado?
  • ¿Qué pasa si manipulo cantidades, tiempos o dependencias?

Este tipo de análisis suele requerir entender realmente el dominio del sistema.

13.17 Errores frecuentes en estas áreas

  • Confiar solo en extensión o tipo declarado del archivo.
  • Guardar archivos en rutas públicas sin control adicional.
  • Deserializar estructuras complejas provenientes del cliente sin validación estricta.
  • Reusar objetos o tokens manipulables como si fueran confiables.
  • Asumir que el frontend impone el flujo correcto del negocio.
  • No modelar explícitamente estados y transiciones del proceso.
Las fallas de lógica no siempre “rompen” la aplicación. Muchas veces la aplicación funciona exactamente como fue implementada, y ese es precisamente el problema.

13.18 Ejemplo integrado

Imaginemos una plataforma donde el usuario sube comprobantes de pago, el sistema los procesa automáticamente y luego habilita beneficios según el estado del pedido. Si el archivo subido no se valida bien, el procesador puede quedar expuesto. Si además el estado del pedido puede manipularse mediante un flujo indirecto o valores enviados por el cliente, el atacante podría activar beneficios sin cumplir realmente las condiciones del negocio.

Este ejemplo muestra cómo archivo, procesamiento y lógica funcional pueden combinarse en una misma cadena de riesgo.

13.19 Defensa en profundidad para archivos, objetos y negocio

Una estrategia madura suele combinar:

  • Restricción fuerte de tipos, tamaños y destinos de archivos.
  • Almacenamiento y procesamiento aislado cuando corresponda.
  • Evitar deserialización de datos no confiables o usar esquemas estrictos.
  • Verificación de estado y secuencia del negocio del lado servidor.
  • Pruebas pensadas para abuso funcional y no solo para validación sintáctica.
  • Monitoreo de comportamientos anómalos o repetitivos.

13.20 Qué debes recordar de este tema

  • La subida de archivos introduce objetos complejos controlados por el usuario y requiere validación y almacenamiento seguros.
  • La deserialización de datos no confiables puede reconstruir estructuras peligrosas o abusables.
  • Las fallas de lógica de negocio no siempre rompen técnicamente el sistema, pero sí rompen su intención de control.
  • El backend debe verificar no solo formato, sino también secuencia, estado y reglas reales del proceso.
  • Probar abuso funcional requiere entender el negocio y no solo el protocolo.

13.21 Conclusión

La seguridad en aplicaciones web no se limita a filtrar cadenas o proteger sesiones. También exige analizar cómo se reciben objetos complejos, cómo se procesan estructuras externas y cómo podría abusarse de la lógica del negocio sin necesidad de una “exploit” clásica. Este tipo de fallas suele pasar desapercibido justamente porque parece uso normal del sistema.

En el próximo tema veremos seguridad en APIs web: REST, JSON, JWT, CORS y rate limiting.