Skip to main content
Blog
Blog

Cómo prevenir la inyección de JavaScript: guía práctica paso a paso

Guía práctica para prevenir la inyección de JavaScript: cierra el XSS, controla scripts de terceros con CSP y SRI e inspecciona sesiones reales.

Aug 21, 2026 Actualizado Aug 22, 2026 11 min read
Cómo prevenir la inyección de JavaScript: guía práctica paso a paso
Tabla de Contenidos

Prevenir la inyección de JavaScript no es una sola tarea. Es cerrar varias puertas distintas que conducen todas a la misma sala: código controlado por un atacante ejecutándose en los navegadores de tus visitantes con todos los privilegios de tu propia página. Algunas de esas puertas son errores en tu código. La mayoría son scripts que cargaste deliberadamente y que luego se volvieron hostiles. Esta guía recorre los controles que realmente reducen el riesgo, en el orden que ofrece más protección con el menor esfuerzo, y es honesta sobre dónde se detiene cada control.

Si primero quieres el contexto, qué es la inyección de JavaScript cubre el mecanismo y todas las vías por las que el código ajeno entra en una página. Este artículo es la continuación práctica: qué hacer al respecto.

Cómo prevenir la inyección de JavaScript, en resumen

  • Cierra la clase XSS en tu propio código. Codifica en la salida, usa sinks del DOM seguros, sanea el HTML no confiable y activa Trusted Types.
  • Restringe de dónde puede provenir el script. Una Content Security Policy estricta basada en nonce bloquea los orígenes de script no autorizados.
  • Fija lo que puedas. Subresource Integrity congela las dependencias estáticas de terceros a un hash conocido.
  • Reduce el árbol de dependencias. Cada script de terceros que eliminas es una vía de inyección menos.
  • Monitoriza el tiempo de ejecución. Vigila cada script que se ejecuta en sesiones reales del navegador, porque la prevención no puede alcanzar el compromiso de un proveedor de confianza.

Las vías de inyección contra las que te defiendes

La prevención solo tiene sentido cuando sabes qué estás previniendo. El JavaScript se inyecta por cuatro vías amplias, y cada una exige un control distinto:

Vía de inyecciónCómo ocurreEl control que ayuda
Cross-site scripting (XSS)Un fallo en tu código permite que la entrada del atacante se ejecute como scriptCodificación de salida, sinks seguros, saneamiento, Trusted Types
Script de terceros comprometidoUn proveedor cuyo tag cargas distribuye código maliciosoRevisión de dependencias, CSP, Subresource Integrity, monitorización en ejecución
Magecart / skimmersLos atacantes plantan código para robar tarjetas en páginas de pago, a menudo vía una dependencia comprometidaMonitorización de la carga en ejecución en el checkout, controles PCI DSS
Extensiones maliciosas / malware del clienteEl código se inyecta en la propia máquina del visitante, en cada sitio que visitaDetección en ejecución; no puedes parchear el navegador del visitante

La primera vía es un fallo de código que te pertenece y puedes corregir. El resto son fallos de confianza: el código fue invitado, o vive en una máquina que no controlas. Esa división importa, porque explica por qué corregir tu propio código es necesario pero nunca suficiente.

Paso 1: Cierra la clase XSS en tu propio código

El cross-site scripting es la única vía de inyección que está enteramente bajo tu control, así que empieza aquí. El XSS ocurre cuando un dato que suministra un usuario se escribe en la página en un lugar donde el navegador lo tratará como código en lugar de texto. Las correcciones están bien entendidas:

  • Codifica en la salida, no solo en la entrada. La misma cadena es segura en un contexto y peligrosa en otro, así que codifica los datos para el contexto exacto donde aterrizan: cuerpo HTML, atributo HTML, JavaScript, URL o CSS. La codificación de salida consciente del contexto es el control anti-XSS más eficaz.
  • Usa sinks del DOM seguros. Asigna datos no confiables con textContent en vez de innerHTML, y evita eval, document.write y setAttribute sobre manejadores de eventos. Estos "sinks" son donde las cadenas inyectadas se vuelven ejecutables.
  • Sanea el HTML que debas renderizar. Cuando realmente necesites renderizar HTML suministrado por el usuario (un comentario con texto enriquecido, por ejemplo), pásalo por un saneador mantenido que elimine el script y los manejadores de eventos, en vez de escribir tu propio filtro.
  • Activa Trusted Types. Trusted Types hacen que los sinks peligrosos del DOM rechacen cadenas simples a nivel del navegador, de modo que una carga inyectada no puede alcanzarlos aunque un error se cuele en la revisión de código. Se aplica mediante una directiva de CSP, lo que conduce directamente al siguiente paso.

Corregir la clase XSS elimina la puerta que un atacante abre explotando tu código. No hace nada respecto a las puertas que abriste tú mismo al cargar el script de otro, que es de donde proviene la mayoría de las brechas modernas del lado del cliente.

Paso 2: Restringe los orígenes con una Content Security Policy

Una Content Security Policy le indica al navegador qué orígenes están autorizados a cargar y ejecutar script en tu página. Una CSP estricta basada en nonce es uno de los controles individuales más fuertes que puedes desplegar contra la inyección: el script que no proviene de un origen permitido, y que no lleva el nonce correcto por solicitud, simplemente no se ejecuta. Los bloques <script> en línea que un atacante inyecta a través de un agujero XSS se bloquean por defecto.

Dos notas prácticas. Primero, prefiere los nonces a las listas de hosts permitidos siempre que puedas; una lista amplia de script-src reabre en silencio vías que pretendías cerrar. Segundo, y este es el límite importante: la CSP autoriza orígenes, no juzga el comportamiento. Una vez que autorizas el dominio de un proveedor para que su script legítimo se ejecute, la CSP no tiene forma de saber si ese script se está portando bien o robando datos de tu formulario. Si el proveedor está comprometido en el origen, su dominio sigue en tu lista de permitidos y la versión maliciosa se carga limpiamente. La CSP es necesaria. No es la respuesta completa.

Paso 3: Fija las dependencias estáticas con Subresource Integrity

Subresource Integrity (SRI) te permite adjuntar un hash criptográfico a un tag <script> o <link>. El navegador calcula el hash del archivo que descargó y se niega a ejecutarlo si el hash no coincide, lo que significa que un archivo estático de terceros no puede ser reemplazado por una versión manipulada sin que el cambio se bloquee.

SRI es excelente para dependencias que no cambian: una versión específica de una biblioteca fijada a su hash exacto. Su límite es la imagen especular de esa fortaleza. No hace nada por los scripts que están pensados para actualizarse (la mayoría de las analíticas, los gestores de tags y los SDK de pago cambian su archivo servido con regularidad), y no hace nada por los scripts cargados dinámicamente por otros scripts. Usa SRI en todas partes donde puedas fijar una versión. No esperes que cubra las partes de tu pila que se actualizan solas.

Paso 4: Reduce y revisa el árbol de dependencias

Cada script de terceros en tu página es una vía de inyección con todos los privilegios de la página. La prevención más barata disponible es tener menos de ellos.

  • Inventaría lo que realmente cargas. A la mayoría de los equipos les sorprende cuántos scripts se ejecutan en una página típica, y cuántos se cargan no directamente sino por otro script (un gestor de tags que carga un proveedor que carga otro proveedor).
  • Elimina lo que no necesitas. Un píxel de marketing sin uso o una herramienta de pruebas A/B abandonada es puro riesgo sin beneficio. Borrarlo elimina una vía de inyección por completo.
  • Minimiza el radio de impacto del gestor de tags. Una cuenta de gestor de tags comprometida puede inyectar "solo otro tag" que parece rutinario. Restringe quién puede publicar y revisa lo que publica.

Este paso no tiene desventaja y ningún control por script puede sustituirlo: un script que no está en la página no puede ser el que se vea comprometido.

Paso 5: Monitoriza el tiempo de ejecución con inspección de la carga en sesiones reales

Los pasos del uno al cuatro reducen la probabilidad. Ninguno puede alcanzar el caso que causa las peores brechas del lado del cliente: un script en el que confías legítimamente, de un origen que permitiste legítimamente, que se vuelve malicioso después de estar ya cargado. La CSP lo deja pasar porque el origen está permitido. SRI lo pierde porque el script está diseñado para actualizarse. Tu propio código está limpio. El único lugar que queda para atraparlo es donde la inyección aterriza realmente, el navegador, en el momento en que el script se ejecuta.

Eso es lo que hace la monitorización en tiempo de ejecución. Construye un inventario de cada script que se ejecuta en sesiones reales de usuario, registra lo que hace cada uno y a dónde envía datos, y alerta cuando aparece un script nuevo, cambia el código de un script conocido o los datos empiezan a fluir hacia un destino inesperado. Esta es la capa que atrapa los skimmers de tipo Magecart y los ataques de proveedores comprometidos que todos los controles preventivos anteriores dejan pasar.

Las herramientas del lado del servidor no pueden proporcionar esto. Un firewall de aplicaciones web o un escaneo del servidor ve el HTML que enviaste, no la carga que un proveedor comprometido cambia después ni el código que una extensión inyecta en la máquina del visitante. La detección tiene que ocurrir en la capa del navegador, en sesiones reales.

Dónde encaja cside: monitorización de scripts en sesiones reales

cside es un único script de JavaScript propio (first-party) que proporciona la capa en tiempo de ejecución de esta lista de comprobación. No reemplaza tu CSP, tu codificación de salida ni tus hashes de SRI; es el control que vigila lo que tus scripts permitidos hacen realmente una vez que están ejecutándose, algo que ninguno de los otros puede ver.

La monitorización de scripts de cside inventaría cada script que se ejecuta en sesiones reales del navegador, analiza la carga completa del script y alerta sobre dominios nuevos, código modificado y flujos de datos inesperados. Funciona en dos modelos operativos: el Script Method obtiene y analiza los scripts de terceros del lado de cside antes de que se ejecuten en la sesión, y el Scan Method para equipos que prefieren una huella más ligera. Se despliega como un solo tag de script desde tu propio origen, sin cambios de DNS; cside obtiene y analiza los scripts de terceros que carga tu página, pero no se sitúa delante del tráfico de tu sitio y no actúa como un proxy.

En las páginas de pago este inventario en tiempo de ejecución también es un requisito de cumplimiento. Los requisitos 6.4.3 y 11.6.1 de PCI DSS 4.0.1 existen precisamente porque el script inyectado en la página de pago es invisible para todos los controles del lado del servidor: 6.4.3 te pide gestionar y autorizar cada script en tus páginas de pago, y 11.6.1 te pide detectar cambios no autorizados en esos scripts y en las cabeceras de la página. La monitorización de scripts en sesiones reales es la respuesta directa a ambos.

Lista de comprobación de prevención

La prevención de la inyección de JavaScript es por capas, y las capas no se solapan:

  1. Codifica la salida y usa sinks del DOM seguros para cerrar la clase XSS en tu propio código.
  2. Despliega una CSP estricta basada en nonce para bloquear los orígenes de script no autorizados.
  3. Añade Subresource Integrity para fijar las dependencias estáticas de terceros.
  4. Reduce y revisa el árbol de dependencias para que haya menos que comprometer.
  5. Monitoriza sesiones reales del navegador para que un script de confianza que se vuelve hostil se atrape en el momento en que actúa.

Acierta con los primeros cuatro y habrás cerrado la mayoría de las puertas. Añade el quinto y podrás ver la única puerta que la prevención nunca puede cerrar del todo: el proveedor de confianza que se ve comprometido después de que lo dejaste entrar.

Lecturas adicionales

Mike Kutlu
Client-Side Security Consultant

Client-side security consultant at cside. 10+ years of experience implementing technology solutions for enterprises (previously at Oracle, Cloudflare, and Splunk). Now helping teams use client-side intelligence to catch & reduce fraud.

FAQ

Frequently Asked Questions

No existe un único control que cierre todas las vías, porque son problemas distintos. Para detener el cross-site scripting corriges cómo tu propio código maneja la entrada y la salida: codifica en la salida, usa sinks del DOM seguros y activa Trusted Types. Para detener la inyección a través de los scripts de terceros que ya cargas, restringes los orígenes con una Content Security Policy, fijas las dependencias estáticas con Subresource Integrity y monitorizas lo que esos scripts hacen realmente en tiempo de ejecución. Lo primero es una corrección de código; lo demás son controles de confianza. Necesitas ambos.

No. Una CSP estricta basada en nonce es uno de los controles individuales más fuertes que puedes desplegar, porque bloquea el script de orígenes que no autorizaste. Pero la CSP autoriza orígenes, no juzga el comportamiento: una vez que permites el dominio de un proveedor, la CSP no puede saber si el script de ese proveedor está robando datos de tu formulario de pago. Si un script permitido se ve comprometido en el origen, la CSP lo deja pasar. Por eso las restricciones de origen deben combinarse con la monitorización en tiempo de ejecución de lo que hacen los scripts permitidos.

Magecart y los ataques a la cadena de suministro no explotan un fallo en tu código; abusan de un script que tú invitaste. La prevención ahí consiste en reducir y vigilar el árbol de dependencias: elimina los scripts de terceros que no necesitas, fija los que puedas con Subresource Integrity, restringe los orígenes con CSP y monitoriza cada script que se ejecuta en sesiones reales del navegador para que un dominio nuevo o una carga modificada genere una alerta. La monitorización de scripts de cside está diseñada para esa última capa.

Normalmente no, porque la inyección suele producirse después de que la página sale de tu servidor, en el navegador del visitante. Un firewall de aplicaciones web o un escaneo del servidor ve el HTML que enviaste, no el script que un proveedor comprometido cambia una hora después, ni el código que la extensión de un atacante inyecta en la máquina del visitante. Detectar el script inyectado exige visibilidad en la capa del navegador: un inventario de cada script que se ejecuta en sesiones reales y a dónde envía datos cada uno.

La inyección de JavaScript es cualquier situación en la que código controlado por un atacante se ejecuta en el navegador de un visitante con los mismos privilegios que los scripts de tu propia página. Llega a la página por varias vías: un fallo de cross-site scripting en tu propio código, un script de terceros que cargas y que se vuelve malicioso, un skimmer de Magecart plantado en una página de pago, o una extensión del navegador en la máquina del visitante. Como el código inyectado hereda el acceso de tu página al DOM, las cookies y los campos de formulario, puede leer lo que los usuarios escriben, redirigir solicitudes o exfiltrar datos, por eso la prevención debe abordar todas las vías, no solo una.

El cross-site scripting es un error en tu propia aplicación: permite que la entrada de un atacante se escriba en la página donde el navegador la trata como código, así que lo corriges cambiando cómo tu código maneja la entrada y la salida. Un script de terceros comprometido es distinto: es código que cargaste deliberadamente de un proveedor y que se volvió hostil después de que lo invitaste, ya sea porque el proveedor sufrió una brecha o porque el archivo fue manipulado en tránsito. El XSS es un fallo de código que es tuyo; una dependencia comprometida es un fallo de confianza en algo que no puedes parchear. Requieren controles distintos, por eso cerrar el XSS nunca cubre por completo el riesgo de terceros.

La codificación en la salida convierte los caracteres que el navegador trataría como marcado o código en sus equivalentes inofensivos de visualización, para el contexto concreto donde aterrizan los datos: cuerpo HTML, atributo, JavaScript, URL o CSS. Codificar para el contexto equivocado deja un hueco, así que la codificación en la salida consciente del contexto es la defensa central contra el XSS. Los Trusted Types añaden una segunda capa a nivel del navegador: hacen que los sinks peligrosos del DOM, como innerHTML, rechacen las cadenas planas, de modo que una carga inyectada no puede alcanzarlos aunque un error pase la revisión. Los Trusted Types se aplican mediante una directiva de la Content Security Policy, así que ambos controles trabajan juntos.

Subresource Integrity fija un script o una hoja de estilos a un hash criptográfico, y el navegador se niega a ejecutar el archivo si el hash no coincide, de modo que una dependencia estática no puede cambiarse por una versión manipulada. Su límite es la otra cara de esa fortaleza: solo funciona con archivos que nunca cambian. Los scripts diseñados para actualizarse (la mayoría de las analíticas, los gestores de etiquetas y los SDK de pago cambian su archivo servido con regularidad) no se pueden fijar, y SRI no hace nada con los scripts que otros scripts cargan dinámicamente en tiempo de ejecución. Úsalo en todo lugar donde puedas fijar una versión, pero no esperes que cubra las partes que se autoactualizan de tu stack, que son justo donde suelen aterrizar los ataques de proveedores comprometidos.

La CSP autoriza orígenes y SRI fija archivos estáticos, así que ambos dejan pasar un script en el que confías legítimamente y que se vuelve malicioso después de cargarse: la CSP sigue viendo un origen autorizado, y SRI no puede fijar un archivo pensado para actualizarse. La monitorización en sesiones reales vigila el único lugar donde ese fallo aparece: el navegador, en el momento en que el script se ejecuta. Construye un inventario de cada script que se ejecuta en sesiones reales de usuario, registra qué hace cada uno y a dónde envía datos, y alerta cuando aparece un script nuevo, cambia el código de un script conocido o los datos fluyen a un destino inesperado. Esa es la capa que atrapa los skimmers tipo Magecart y los ataques de proveedores comprometidos que los controles preventivos no pueden ver.

PCI DSS 4.0.1 añadió dos requisitos precisamente porque el script inyectado en una página de pago es invisible para los controles del lado del servidor. El requisito 6.4.3 pide que gestiones y autorices cada script que se ejecuta en tus páginas de pago, y el 11.6.1 pide que detectes cambios no autorizados en esos scripts y en las cabeceras HTTP de la página. Ambos describen visibilidad en la capa del navegador: un inventario de lo que realmente se ejecuta en sesiones reales y una alerta cuando cambia. La monitorización de scripts en sesiones reales es la respuesta directa a ambos, por eso los equipos con una fecha límite de PCI suelen aplicarla primero al flujo de pago.

Sí. Una extensión del navegador maliciosa o con demasiados permisos se ejecuta en la propia máquina del visitante y puede inyectar script en cada sitio que abre, incluido el tuyo, con acceso total a la página renderizada. No puedes prevenir esto como corriges tu propio código o blindas a un proveedor, porque la extensión vive por completo fuera de tu control: no hay nada en tu servidor que parchear. Lo que sí puedes hacer es detectarla: la monitorización en tiempo de ejecución que observa lo que se ejecuta en sesiones reales puede señalar el script que ninguna parte legítima de tu página cargó, que a menudo es la única señal de que una extensión está manipulando la sesión de un visitante.

Primero, confirma lo que ves: usa la visibilidad en la capa del navegador para identificar el script exacto, el origen del que vino y a dónde envía datos, para actuar sobre pruebas y no sobre una suposición. Si es una dependencia de terceros comprometida, elimina o bloquea ese script de inmediato y revoca cualquier credencial que pudiera haber expuesto; si es un fallo de XSS, parchea el manejo de entrada vulnerable y corrige la codificación de la salida afectada. En las páginas de pago, trátalo como un posible incidente de datos de titulares de tarjeta bajo PCI DSS y sigue tu plan de respuesta. Después cierra la brecha que lo permitió (una directiva de CSP ausente, una dependencia sin fijar o una cuenta de gestor de etiquetas con demasiados publicadores) y mantén la monitorización en sesiones reales para que una reaparición se atrape en el momento en que actúe.

Monitoriza y protege tus scripts de terceros

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Empieza gratis o prueba Business con una versión de prueba de 14 días.

Interfaz del panel de cside que muestra la monitorización de scripts y el análisis de seguridad
Related Articles
Reservar una demo

¿Quieres verlo en detalle con un ingeniero?

Treinta minutos, sobre tu propio sitio. Nada de diapositivas.

Te enseñaremos:

Qué scripts de terceros se están ejecutando ahora mismo en tu sitio
En qué punto estás con los requisitos 6.4.3 y 11.6.1 de PCI DSS
Qué parte de tu tráfico son bots y agentes de IA

¿Prefieres mandarnos una pregunta?

Buscando huecos libres…

Solo humanos de verdad. Nos daríamos cuenta.

¿Problemas para reservar? Abrir el calendario en una pestaña nueva

¿Qué quieres resolver?

Cuéntanoslo en una línea y te responderemos con algo útil, no con un discurso genérico.

Solemos ayudar con:

Ver qué scripts de terceros se ejecutan en tu sitio
Evidencias para PCI DSS 6.4.3 y 11.6.1
Bots, agentes de IA y robo de cuentas

¿Prefieres reservar una hora? Elegir un hueco