Aikido

Los 10 principales problemas de seguridad de aplicaciones y cómo protegerse

Joel HansJoel Hans
|
#

Sabes que tu última aplicación web es inherentemente vulnerable a todo tipo de ataques. También sabes que la seguridad de las aplicaciones nunca puede ser perfecta, pero puedes mejorarla mañana respecto a ayer.

El problema es que, ya sea que estés utilizando herramientas de seguridad de nivel empresarial (es decir, caras y complejas), o hayas improvisado un puñado de proyectos de código abierto en un pipeline de CI/CD o en Git commit hooks y esperes lo mejor, tu conjunto de herramientas no puede ayudarte a ver:

  • Cómo tu aplicación podría ser vulnerable debido a prácticas de programación menos que ideales, dependencias inseguras y más allá.
  • Dónde es más probable que se oculten las vulnerabilidades, hasta líneas de código individuales (LOCs) o entradas en su package.json archivo.
  • Por qué deberías corregir ciertas vulnerabilidades de inmediato y por qué otras tienen una prioridad menor.

Aikido existe para hacer que la seguridad de las aplicaciones sea relevante y eficiente para los desarrolladores que necesitan aplicar las correcciones de seguridad adecuadas rápidamente y volver a entregar código. Al igual que hacemos en nuestra plataforma de seguridad centrada en el desarrollador, vamos a reducir el ruido en torno a las vulnerabilidades comunes y nos centraremos en tres detalles esenciales:

  • El TL;DR (resumen), que te enseñará lo suficiente para tener miedo... y las palabras clave adecuadas para continuar tu búsqueda educativa.
  • Una respuesta concisa a la pregunta, “¿Esto me afecta?” con un claro sí o no (✅ o 🙅) y una breve explicación.
  • Consejos rápidos en respuesta a “¿Cómo puedo solucionarlo?” que no implican herramientas costosas o refactorizaciones caras.

#1: Inyección SQL && Inyección NoSQL

TL;DR: Esta vulnerabilidad clásica es posible gracias a la entrada de usuario no saneada y no validada, lo que permite a los atacantes ejecutar consultas directamente contra su base de datos. Desde allí, pueden extraer datos, modificar registros o eliminarlos a voluntad, anulando por completo cualquier otra medida de seguridad de la aplicación que haya implementado.

Un ejemplo de cómo los ataques de inyección SQL afectan la seguridad de su aplicación al revelar datos confidenciales.

¿Esto me afecta?

  • ✅ si su aplicación interactúa con una base de datos SQL o NoSQL en algún momento. Los ataques de inyección existen desde hace décadas, y los ataques automatizados comenzarán inmediatamente a sondear sus endpoints con exploits comunes.
  • 🙅 si no tiene contenido dinámico basado en registros de la base de datos. Esto podría deberse a que su aplicación es completamente del lado del cliente, utiliza un generador de sitios estáticos (SSG) o realiza renderizado del lado del servidor con una base de datos pero nunca acepta entradas de los usuarios.

¿Cómo lo soluciono? En primer lugar, sanee y valide todas las entradas de usuario para eliminar caracteres o cadenas no deseados. Aproveche las bibliotecas y frameworks de código abierto que permiten consultas parametrizadas, y nunca concatene la entrada del usuario en una consulta de base de datos. Si utiliza Node.js, considere nuestro motor de seguridad de código abierto Runtime, que le protege de forma autónoma contra ataques de inyección SQL/NoSQL y más.

#2: cross-site scripting (XSS)

TL;DR: XSS es otro ataque de inyección que permite a un atacante enviar un script malicioso a otro, potencialmente recopilando sus credenciales de autenticación o datos confidenciales.

¿Esto me afecta?

  • ✅ si su aplicación acepta entradas de usuario y las muestra en otro lugar como contenido dinámico.
  • 🙅 si no acepta ninguna entrada de usuario.

¿Cómo lo soluciono? Al igual que con los ataques de inyección SQL/NoSQL, debe validar la entrada del usuario cuando incluya dicha entrada dentro del href atributo de las etiquetas de anclaje para asegurar que el protocolo no sea javascript. Tenga cuidado al usar métodos de JavaScript como innerHTML o los de React como dangerouslySetInnerHTML, que pueden ejecutar arbitrariamente cualquier código incrustado en la cadena durante la salida. Independientemente de su enfoque, sanee la salida HTML con saneadores de código abierto como DOMPurify para enviar solo HTML limpio y no ejecutable a sus usuarios.

#3: Falsificación de solicitud del lado del servidor (SSRF)

En resumen: Los ataques SSRF ocurren cuando un actor malicioso abusa de su aplicación para interactuar con su red subyacente, operándola como un proxy para saltar a servicios potencialmente más vulnerables o lucrativos.

¿Esto me afecta?

  • ✅ si su aplicación interactúa con otro servicio o API que realiza una operación específica con datos de usuario, incluso si ha utilizado listas blancas (allowlists) para restringir el tráfico solo entre puntos finales conocidos y de confianza.
  • 🙅 si su aplicación es verdaderamente estática.

¿Cómo lo soluciono? Aunque una expresión regular (regex) para validar direcciones IP o nombres de host es un buen comienzo, suele ser propensa a bypasses como la codificación octal. Dos soluciones más fiables son usar una lista blanca (allowlist) y el analizador de URL nativo de su plataforma para restringir la entrada solo a hosts seguros y conocidos, y deshabilitar las redirecciones en las solicitudes fetch. Dependiendo de su framework, también puede aprovechar libremente proyectos de código abierto —como ssrf-req-filter para Node.js— para rechazar correctamente cualquier solicitud a hosts internos.

#4: Recorrido de rutas (Path traversal)

En resumen: Esta vulnerabilidad de seguridad permite a los atacantes acceder a archivos y directorios en su servidor web haciendo referencia a archivos mediante ../ secuencias o incluso rutas absolutas. Utilizando tácticas engañosas como la doble codificación, los atacantes pueden usar jerarquías de carpetas/archivos específicas del framework o nombres de archivo comunes para encontrar información valiosa.

Un ejemplo de ataque de recorrido de rutas contra una aplicación Node.js con una seguridad de aplicación deficiente, revelando sus secretos.

¿Esto me afecta?

  • ✅. Su aplicación se ejecuta en un servidor web e incluye referencias al sistema de archivos; no hay forma de evitar esto.

¿Cómo lo soluciono? Su primer paso es eliminar cualquier archivo sensible, como los que contienen variables de entorno o secretos, del directorio raíz de su servidor web y establecer un proceso para evitar futuros errores.

es nunca almacenar archivos sensibles, como los que contienen variables de entorno o secretos, en el directorio raíz de su servidor web. Además, no almacene estos archivos en ninguna carpeta destinada a ser de acceso público, como las carpetas /static y /public de un Next.js project. Finalmente, elimine ../ los separadores de ruta y sus variantes codificadas de la entrada del usuario.

Runtime también funciona fantásticamente bien para el recorrido de rutas (path traversal)… solo digo.

#5: Inyección de Entidades Externas XML (XXE)

TL;DR: Los ataques XXE aprovechan una debilidad en los analizadores XML que permite que las entidades externas, referenciadas por una definición de tipo de documento (DTD), sean recuperadas y procesadas sin validación ni saneamiento. El tipo y la gravedad del ataque están limitados principalmente por las habilidades del atacante y por cualquier seguridad/permisos a nivel de sistema operativo de tu proveedor de infraestructura.

¿Esto me afecta?

  • ✅ si procesas XML por cualquier motivo, incluidos los flujos de autenticación de inicio de sesión único (single sign-on) utilizando SAML.
  • 🙅 si no tienes que lidiar con XML en tu aplicación.

¿Cómo lo soluciono? Deshabilita la resolución de DTD externas en tu analizador XML. Es probable que no puedas rechazar las DTD por completo, ya que es normal que algunas cargas útiles XML las contengan; simplemente no permitas que tu analizador XML haga nada con ellas.

#6: Deserialización

En resumen: Los atacantes pueden enviar datos maliciosos a través de una función de deserialización integrada en tu aplicación (como unserialize() de node-serialize) para ejecutar código de forma remota, realizar un ataque de denegación de servicio o incluso crear un shell inverso.

¿Esto me afecta?

  • ✅ si tu aplicación deserializa datos directamente de la interacción del usuario o a través de funciones/servicios en segundo plano como cookies, formularios HTML, APIs de terceros, almacenamiento en caché y más.
  • 🙅 si ejecutas una aplicación completamente estática sin nada de lo anterior.

¿Cómo lo soluciono? En general, evita deserializar datos de entrada de usuario (también conocidos como no confiables). Si es imprescindible, solo acepta dichos datos de usuarios autenticados y autorizados basándote en firmas de confianza, certificados y proveedores de identidad.

#7: Inyección de shell/inyección de comandos

TL;DR: Tu aplicación pasa la entrada del usuario directamente al shell subyacente del sistema operativo en el que se ejecutan tu servidor web y tu aplicación, permitiendo a los atacantes ejecutar comandos arbitrarios o recorrer el sistema de archivos, a menudo con privilegios suficientes para extraer datos o pivotar a otro sistema.

¿Esto me afecta?

  • ✅ si tu aplicación interactúa directamente con el sistema de archivos o el shell, como un comando UNIX como cat.
  • 🙅 si ya utilizas una API o método de un framework para pasar argumentos de forma segura al comando que necesitas ejecutar, o no necesitas interactuar con el sistema de archivos/shell, como en un SSG.

¿Cómo lo soluciono? Evita aceptar la entrada del usuario directamente en los comandos o llamarlos directamente. En su lugar, utiliza la API/método de tu framework, como child_process.execFile() en Node.js, que te permite pasar argumentos en una lista de cadenas de texto. Incluso con esa protección, ejecuta siempre tus aplicaciones con los privilegios mínimos necesarios para la lógica de negocio requerida para evitar que un atacante se “escape” del servidor web y acceda a rootcarpetas y archivos solo de root.

Y sí, volvemos para un recordatorio amistoso más de añadir Runtime a cualquier proyecto Node.js con un solo comando (npm add @aikidosec/runtime || yarn install @aikidosec/runtime) para proteger instantáneamente tu aplicación contra ataques comunes de inyección de shell/comandos.

#8: Inclusión de archivos locales (LFI)

TL;DR: Los ataques LFI implican engañar a tu aplicación para que exponga o ejecute archivos en el sistema donde se ejecuta tu servidor web, lo que permite a los atacantes extraer información o ejecutar código de forma remota. Mientras que el "path traversal" solo permite a los atacantes leer archivos, los ataques LFI ejecutan esos archivos dentro de tu aplicación, exponiéndote a una larga lista de vulnerabilidades de seguridad de aplicaciones como la ejecución remota de código (RCE).

¿Esto me afecta?

  • ✅ si tu aplicación utiliza la ruta a un archivo como entrada de usuario.
  • 🙅 si tu aplicación no requiere que los usuarios proporcionen rutas para completar ninguna acción.

¿Cómo lo soluciono? Siempre sanea la entrada del usuario para evitar los métodos de path traversal mencionados anteriormente. Si debes incluir archivos en el sistema de archivos local más allá de los que se encuentran típicamente en carpetas "seguras" /public o /static , utiliza una lista blanca de nombres de archivos y ubicaciones que tu aplicación tenga permiso para leer y ejecutar.

#9: Contaminación de prototipos

En resumen: Esta vulnerabilidad específica de JavaScript permite a un atacante manipular los objetos globales de tu aplicación utilizando __proto__. El nuevo objeto se hereda entonces en toda tu aplicación, lo que podría darles acceso a datos confidenciales o escalar aún más sus privilegios.

¿Esto me afecta?

  • ✅ si estás utilizando JavaScript.
  • 🙅 si estás utilizando cualquier cosa excepto JavaScript!

¿Cómo lo soluciono? Comienza saneando las claves de la entrada del usuario utilizando listas blancas o una librería auxiliar de código abierto. Puedes ampliar tu protección utilizando Object.freeze() Object.freeze() para evitar cambios en un prototipo, o incluso utilizando la --disable-proto=delete bandera --disable-proto=delete ofrecida con Node.js.

#10: Redirecciones abiertas

En resumen: En este vector común de phishing, los atacantes elaboran una URL personalizada como https://www.example.com/abc/def?&success=true&redirectURL=https://example.phishing.com para engañar a tu aplicación y redirigir a usuarios desprevenidos a un sitio web malicioso. Además, los atacantes pueden encadenar redirecciones con otras vulnerabilidades para un impacto aún mayor, lo que lleva a la toma de control de cuentas y más.

Cómo una redirección abierta oculta sitios nefastos en URLs casi ilegibles para afectar la seguridad de tu aplicación.

¿Esto me afecta?

  • ✅ si tu aplicación redirige a los usuarios a otra página/vista después de completar una acción, como enviarlos a example.app/dashboard después de una autenticación exitosa.
  • 🤦 si sigues con esa vida de generación estática.

¿Cómo lo soluciono? Primero, elimina las redirecciones basadas en parámetros de tu aplicación y reemplázalas por redirecciones fijas basadas en una lista de permitidos (allowlist) de dominios y rutas de confianza a los que puedes redirigir a los usuarios después de que realicen acciones específicas. Esto podría degradar ligeramente la experiencia del usuario, pero es un compromiso significativo para mejorar la seguridad de la aplicación, no uno que los deje culpándote por los gastos extraños en el extracto de su tarjeta de crédito.

¿Qué sigue para la seguridad de tu aplicación?

Si te sientes abrumado por el alcance de los ataques y todo el trabajo necesario para protegerte contra ellos, debes saber que no estás solo.

Nadie espera que resuelvas todos estos problemas de seguridad y posibles vulnerabilidades por ti mismo. Los ataques de inyección SQL, por sí solos, han existido durante décadas, y la gente sigue encontrando CVEs en aplicaciones, frameworks y librerías sofisticadas constantemente. Esto no significa que debas tomarte estos problemas de seguridad a la ligera; si tu proyecto cumple con el ✅ para cualquiera de estos 10 principales problemas de seguridad de aplicaciones, deberías empezar a tomar medidas.

Primero, regístrate en Aikido para empezar a centrarte en las amenazas genuinas para la seguridad de tu aplicación. En dos minutos, y de forma gratuita, puedes escanear repositorios y obtener detalles relevantes además de remediaciones guiadas para las vulnerabilidades más críticas, basándose en la arquitectura específica de tu aplicación y las características, funciones y librerías de ayuda que hayas implementado. Con Aikido, reducirás el alcance a lo que realmente importa e implementarás soluciones inteligentes más rápido, y serás informado al instante de los nuevos problemas de seguridad introducidos en tus últimos commits.

A continuación, añade Runtime, nuestro motor de seguridad embebido de código abierto, a tus aplicaciones Node.js. Runtime protege instantánea y autónomamente tus aplicaciones contra diversos ataques de inyección, contaminación de prototipos y path traversal, bloqueándolos a nivel de servidor, pero sin el coste y la complejidad de los firewalls de aplicaciones web o las plataformas de gestión de seguridad de aplicaciones basadas en agentes. Runtime te da la confianza de que tu aplicación y tus usuarios están a salvo de estos problemas de seguridad comunes, pero también puede enviar datos en tiempo real a Aikido para darte visibilidad sobre los vectores de ataque actuales y ayudarte a priorizar las correcciones.

Ahora estás en el camino correcto, con una imagen más clara sobre:

  • Cómo tu aplicación es vulnerable de más formas de las que podrías haber pensado.
  • Dónde deberías centrar tu tiempo y atención para solucionar primero los problemas más críticos.
  • Por qué la seguridad de las aplicaciones y el escaneo de vulnerabilidades no es un esfuerzo puntual, sino un proceso continuo, uno que se facilita mucho con Aikido.
4.7/5

Protege tu software ahora.

Empieza gratis
Sin tarjeta
Solicitar una demo
Sus datos no se compartirán · Acceso de solo lectura · No se requiere tarjeta de crédito

Asegúrate ahora.

Proteja su código, la nube y el entorno de ejecución en un único sistema central.
Encuentre y corrija vulnerabilidades de forma rápida y automática.

No se requiere tarjeta de crédito | Resultados del escaneo en 32 segundos.