In this article
Seguridad de JavaScript
Vulnerabilidades de JavaScript y buenas prácticas explicadas
Como casi cualquier lenguaje de programación, JavaScript también tiene posibles riesgos de seguridad. La explotación de vulnerabilidades de JavaScript puede manipular datos, redirigir sesiones, modificar y robar información, entre muchas otras cosas. Aunque normalmente se considera que JavaScript es una tecnología del lado del cliente, sus problemas de seguridad también pueden afectar los entornos del lado del servidor.
La mejor defensa contra las vulnerabilidades más comunes de JavaScript es conocerlas e implementar los controles adecuados para reducir la exposición.
Vulnerabilidades de seguridad de JavaScript en 2023
Entre las vulnerabilidades de JavaScript más comunes se encuentran el Cross-Site Scripting (XSS), el código malicioso, los ataques de intermediario y la explotación de vulnerabilidades en el código fuente de las aplicaciones web. Puedes prevenirlas analizando tu código para detectar vulnerabilidades durante el desarrollo y capacitando a tus desarrolladores en seguridad.
En este artículo, analizaremos las vulnerabilidades más comunes de JavaScript y cómo prevenirlas mediante enfoques de seguridad modernos y herramientas de prueba populares (por ejemplo, herramientas de auditoría y análisis de código, un escáner de vulnerabilidades de JavaScript, etc.).
¿Qué es la seguridad de JavaScript?
La seguridad de JavaScript abarca la investigación, prevención, protección y resolución de problemas de seguridad en aplicaciones que usan JavaScript.
JavaScript es una tecnología fundamental para crear aplicaciones web y también es muy popular para desarrollar aplicaciones del lado del servidor, de escritorio e incluso móviles. Sin embargo, su enorme popularidad también lo convierte en un objetivo prioritario para los hackers, que buscan atacarlo mediante distintos vectores de ataque. Como JavaScript se usa principalmente en el front-end, tiene sentido empezar por los problemas de seguridad de JavaScript en los navegadores.
Los proveedores de software también han reconocido estos problemas de seguridad de JavaScript y han respondido con software de análisis de seguridad de JavaScript y diversas herramientas de pruebas de seguridad que hacen que las aplicaciones sean más seguras y reducen considerablemente los riesgos. Prueba nuestro verificador de código JavaScript para encontrar vulnerabilidades en tu código.
¿Cuáles son las vulnerabilidades más comunes de JavaScript?
Entre los vectores de ataque más comunes de JavaScript se encuentran la ejecución de scripts maliciosos, el robo de datos de sesión establecidos de un usuario o de datos del localStorage del navegador, el engaño a los usuarios para que realicen acciones no deseadas y la explotación de vulnerabilidades en el código fuente de las aplicaciones web.
Por supuesto, esta lista no es exhaustiva; más bien, se centra en el aspecto del front-end de las aplicaciones web.
8 vulnerabilidades de seguridad de JavaScript

Comienza con Capture the Flag
Aprende a resolver desafíos de Capture the Flag con nuestro taller virtual 101 a pedido.
1. Vulnerabilidades en el código fuente
A menudo, las vulnerabilidades en el código fuente pueden combinarse con otras brechas de seguridad de JavaScript, incluso varias a la vez. Por desgracia, en esos casos, la ofuscación de JavaScript por sí sola no puede prevenir ni ocultar este tipo de vulnerabilidades. Como JavaScript es un lenguaje interpretado, no compilado, proteger el código de la aplicación para que los posibles hackers no lo examinen sería prácticamente imposible con este método. Aun así, la ofuscación sigue siendo una buena práctica, ya que ralentiza los intentos de ingeniería inversa de los hackers.
Otra causa de las brechas de seguridad en el código fuente es el uso generalizado de paquetes y bibliotecas públicas. NPM, uno de los principales actores del ecosistema de JavaScript, ofrece más de un millón de paquetes en su registro. Aunque la gran variedad disponible es sin duda una ventaja, también significa que podría haber una enorme cantidad de vulnerabilidades ocultas en los paquetes instalados en los proyectos de aplicaciones web.
Además, los desarrolladores suelen instalar paquetes incluso para las tareas más simples, lo que amplía las dependencias de sus proyectos. Esto, por supuesto, puede generar problemas de seguridad y otras consecuencias de gran alcance.
Supervisar y resolver todas las posibles vulnerabilidades en las dependencias de una aplicación puede llevar mucho tiempo y trabajo. Las herramientas de auditoría pueden ayudar a automatizar y agilizar el proceso.
Un enfoque integral para prevenir problemas de seguridad de JavaScript en el código fuente debe incluir lo siguiente:
Mejorar el conocimiento de las buenas prácticas entre los desarrolladores
Auditar correctamente el código de la aplicación para detectar posibles vulnerabilidades
Escribir pruebas unitarias no solo para comprobar que el código se comporte como se espera, sino también que se ejecute de forma segura
Implementar herramientas que analicen las aplicaciones de forma dinámica e identifiquen problemas de seguridad de JavaScript en paquetes y bibliotecas de terceros
2. Ejecución no deseada de scripts
La mayoría de los ataques de ejecución no deseada de scripts involucran cross-site scripting (XSS). Un aspecto particularmente preocupante de JavaScript es la forma en que interactúa con el Modelo de objetos del documento (DOM) de una página web, lo que permite insertar y ejecutar scripts en las computadoras cliente a través de la web. Por eso, aunque existen varios tipos de ataques XSS, todos tienen en común que hacen que un script no confiable aparezca y se ejecute en el navegador del usuario.
Uno de los escenarios más básicos de ataque XSS suele verse en sitios de foros, donde los usuarios pueden ver los mensajes de otras personas en la página. Si el HTML o JavaScript de un mensaje no se codifica correctamente, usuarios malintencionados podrían publicar un script en el foro.
Al publicar un script de ese tipo, todos los usuarios finales se convierten en víctimas sin darse cuenta y facilitan el ataque con solo usar la aplicación, mientras el código malicioso parece formar parte de la página web.
Para prevenir los ataques XSS, los desarrolladores deben aplicar la sanitización —una combinación de escape, filtrado y validación de datos de texto— al manejar la entrada del usuario y los datos que devuelve el servidor.
3. Escapar/codificar la entrada del usuario
Los ataques XSS se basan en proporcionar datos que contienen ciertos caracteres especiales usados en el HTML, JavaScript o CSS de una página web. Cuando el navegador renderiza la página y encuentra esos caracteres, los interpreta como parte del código de la página, en lugar de como un valor que debe mostrar. Esto permite que el atacante salga de un campo de texto e inserte código adicional del lado del navegador que se ejecuta.
Para evitarlo, siempre que se devuelvan en una respuesta datos proporcionados por el navegador —ya sea de forma inmediata o recuperados de una base de datos—, estos caracteres especiales deben reemplazarse por sus códigos de escape.
Por ejemplo, los caracteres < y >, que se usan para delimitar entidades HTML, pueden reemplazarse por < y >, lo que indica al navegador que muestre esos caracteres en lugar de interpretarlos como entidades HTML. Si los datos proporcionados por el navegador se devuelven en un contexto de JavaScript, los caracteres no alfanuméricos deben escaparse mediante xNN, donde NN es el valor hexadecimal ASCII del carácter.
4. Filtrar la entrada
En algunos casos, puede ser preferible simplemente eliminar los caracteres peligrosos de los datos recibidos como entrada. Esto puede ofrecer cierto grado de protección, pero no debe ser la única medida para protegerse contra la manipulación de datos. Los atacantes pueden usar diversas técnicas para evadir estos filtros.
5. Validación de entradas
Siempre que sea posible, se debe validar la entrada proporcionada por el navegador para garantizar que solo contenga los caracteres esperados. Por ejemplo, los campos de números de teléfono solo deberían aceptar números y, quizá, guiones o paréntesis. Las entradas que incluyan caracteres fuera del conjunto esperado deben rechazarse de inmediato. Los filtros deben configurarse para aceptar los caracteres permitidos y rechazar todos los demás.
6. Depender únicamente de la validación del lado del cliente
Aunque todos los métodos anteriores son buenos y funcionan bien en los navegadores, los hackers pueden usar herramientas especiales para enviar datos directamente al servidor y así evitar las validaciones del lado del cliente. Esto permitiría enviar datos potencialmente maliciosos o no verificados al servidor. Sin una validación adicional del lado del servidor, los datos almacenados podrían dañarse o reemplazarse por datos erróneos.
La mejor práctica recomendada para prevenir estos escenarios es implementar la validación tanto en el cliente como en el servidor. Este enfoque reduce el riesgo de recibir datos incorrectos y, a la vez, ofrece funciones de validación en el cliente que mejoran la experiencia del usuario final.
Validar solo en el servidor puede resultar molesto para el usuario, ya que quizá tenga que completar formularios en línea varias veces antes de superar todas las validaciones. La validación con JavaScript debe informar al usuario de inmediato si hay problemas con los datos que ingresó, mientras que la validación del servidor garantiza que solo los datos esperados lleguen a la aplicación.
7. Robo de datos de sesión
Los scripts del lado del cliente en el navegador pueden ser muy potentes, ya que tienen acceso a todo el contenido que una aplicación web devuelve al navegador. Esto incluye las cookies, que podrían contener datos confidenciales, como los ID de sesión de los usuarios. De hecho, una forma común de explotar ataques XSS consiste en enviar los tokens de ID de sesión del usuario al atacante para que pueda secuestrar la sesión.
Para prevenir esto, la mayoría de los navegadores ahora admiten el atributo Http-Only en las cookies. Cuando el servidor establece una cookie en el navegador, el atributo Http-Only indica al navegador que no permita el acceso a esa cookie desde el DOM. Esto impide que los ataques basados en scripts del lado del cliente accedan a los datos confidenciales almacenados en esas cookies.
Los datos almacenados localmente y en el almacenamiento de sesión del navegador también pueden robarse de la misma manera, aunque no es posible protegerlos mediante el acceso al DOM. Por lo tanto, es mejor evitar guardar información confidencial, como tokens, en el almacenamiento del navegador, salvo que sea necesario debido a características específicas de la arquitectura de la aplicación web.
8. Inducir a los usuarios a realizar acciones no deseadas
Los ataques de falsificación de solicitudes entre sitios (CSRF) intentan engañar al navegador para que ejecute solicitudes maliciosas en sitios web en los que el usuario ya inició sesión, incluso si el sitio no está abierto en ese momento. Si las sesiones del sitio objetivo se basan en cookies, las solicitudes a ese sitio pueden incluir automáticamente cookies de autorización.
Los hackers también pueden crear sus propias páginas web y hacer que ejecuten solicitudes maliciosas en segundo plano a otros sitios cuando el usuario las abre. También pueden usar redes sociales, foros y otras plataformas para publicar enlaces maliciosos u otro contenido que obligue a los navegadores a realizar llamadas inadvertidas a otros sitios usando las cookies de sesión del usuario.
La técnica general para evitar esta vulnerabilidad consiste en implementar la tokenización de la comunicación entre el cliente y el servidor, introduciendo un token adicional que no se almacene en las cookies. Se deben generar tokens para cada formulario del sitio web al establecer la sesión y enviarlos junto con cada solicitud mientras el usuario esté en el sitio web.
¿Cómo abordar los problemas de seguridad de JavaScript?
La protección de aplicaciones y servidores contra las vulnerabilidades de JavaScript se puede lograr adoptando las buenas prácticas de seguridad de JavaScript y usando herramientas de análisis avanzadas.
En el mundo del desarrollo web, los ingenieros de software deben mantenerse al tanto de los nuevos riesgos de seguridad de JavaScript que surgen constantemente. No solo es importante realizar pruebas funcionales en las aplicaciones; usar herramientas de pruebas de seguridad de JavaScript de forma periódica también es fundamental para prevenir vulnerabilidades. Por último, seguir algunas buenas prácticas simples y comunes sin duda aumentará la resiliencia de tus aplicaciones.
Las siguientes buenas prácticas de seguridad de JavaScript pueden reducir este riesgo.
Evita eval()**: No uses este comando en el código, ya que simplemente ejecuta el argumento proporcionado si es una expresión de JavaScript. Esto significa que, si el hacker logra manipular el valor de entrada, podrá ejecutar cualquier script que quiera. En su lugar, elige opciones alternativas más seguras.
Cifra: Usa HTTPS/SSL para cifrar los datos que se intercambian entre el cliente y el servidor.
Configura cookies seguras: Para garantizar que se use SSL/HTTPS, configura tus cookies como “secure”, lo que limita su uso a páginas web seguras.
Configura claves de acceso a la API: Asigna tokens individuales a cada usuario final. Si estos tokens no coinciden, se puede denegar o revocar el acceso.
Usa métodos seguros para manipular el DOM:Los métodos como innerHTML son potentes y potencialmente peligrosos, ya que no limitan ni escapan o codifican los valores que reciben. En cambio, usar un método como innerText permite escapar automáticamente el contenido potencialmente peligroso. Esto resulta especialmente útil para prevenir ataques XSS basados en el DOM.
Identificar posibles problemas de seguridad en JavaScript es un primer paso esencial para prevenir vulnerabilidades durante el desarrollo de aplicaciones. Prueba tu código ahora con un escáner de vulnerabilidades de código abierto.
Snyk para la seguridad de JavaScript
Desde la primera línea de código hasta la última dependencia de npm, Snyk protege tus aplicaciones de JavaScript directamente desde tu IDE, CLI y flujos de trabajo de Git.