Imagina que contratas a un proveedor para hacer una aplicación con formularios donde tus clientes ponen su nombre y un mensaje. Todo va bien… hasta que un día alguien escribe algo “raro” y, sin que lo notéis, tu web ejecuta eso como si fuera una orden.
Ese truco se llama XSS y puede abrir la puerta a robos de cuenta, fraudes o pantallas falsas que piden contraseñas.
Este post está pensado para no técnicos. Vas a aprender:
- Qué es XSS y cómo funciona a nivel práctico.
- Qué señales mirar en tus formularios.
- Pruebas simples que puedes hacer tú mismo.
- Qué pedir y exigir a tu proveedor si algo no cuadra.

¿Qué es XSS? (explicado sin jerga, pero con técnica)
- Definición corta: XSS (Cross-Site Scripting) ocurre cuando tu web muestra sin proteger algo que escribió un usuario y el navegador lo interpreta como código (JavaScript) en lugar de texto.
- Cómo sucede: el dato viaja desde un campo (o URL) hasta una página y se inserta allí tal cual. Si incluye etiquetas como
<script>…</script>
, el navegador las ejecuta. - Tres situaciones habituales:
- Reflejado: el dato va en la URL o formulario y se “refleja” en la respuesta (por ejemplo, en un buscador interno).
- Almacenado: el dato malicioso queda guardado (comentarios, perfiles, chat) y afecta a cualquiera que vea esa página.
- DOM-Based: el propio JavaScript del sitio coloca el dato del usuario en la página usando métodos inseguros (p. ej.,
innerHTML
), sin pasar por el servidor.
¿Cómo se resuelve (en pocas palabras)?
- Mostrar como texto, no como código: “escapar” la salida según el contexto (HTML, atributos, URLs, JS).
- Validar/sanitizar lo que aceptas: permitir solo lo necesario; si aceptas texto con formato, usa una lista permitida (allowlist).
- Añadir barreras: una CSP (Content-Security-Policy) limita qué scripts pueden ejecutarse; cookies de sesión con HttpOnly, Secure, SameSite dificultan el robo de sesión.
- Evitar APIs peligrosas: no usar
innerHTML
,eval
,new Function
con datos de usuario. - Revisar puntos críticos: seguridad en formularios, buscadores, URLs con parámetros y paneles internos.
¿Por qué debería importarte?
Porque si ocurre XSS en tu web:
- Pueden entrar en cuentas de clientes o de tu equipo.
- Pueden mostrar pantallas falsas para robar contraseñas o tarjetas.
- Puedes tener un problema legal (RGPD) y reputacional: avisos a clientes, sanciones y costes de emergencia.
Aunque el desarrollo lo haga un tercero, tu empresa es la cara visible ante clientes y autoridades.
Pruebas simples que puedes hacer tú mismo
Haz estas pruebas solo en tu web (o con permiso). Mejor si tienes un entorno de pruebas.
Objetivo: comprobar que lo que escribe un usuario se muestra como texto y no “cobra vida”.
1) Prueba de “texto con formato”
Copia y pega esto en un campo visible (por ejemplo, “Nombre” o “Comentario”):
cssCopiarEditar<b>Nombre de Prueba</b>
- Resultado seguro: lo ves tal cual, con los símbolos
<
y>
. - Señal de riesgo: aparece en negrita. La web está interpretando lo escrito, no mostrándolo como texto.
2) Prueba de “alerta” (opcional, muy clara)
Copia y pega:
php-templateCopiarEditar<script>alert("Ejecución de XSS en ventana tipo alert")</script>
- Resultado seguro: se ve como texto o se ignora.
- Señal de riesgo clara: salta una ventanita con “XSS”. Eso indica ejecución.
Ojo: si no salta, no garantiza seguridad total (puede haber filtros parciales), pero es buena señal.
3) Prueba en buscadores internos y filtros
En un buscador o filtro de tu web, escribe:
bashCopiarEditar<<XSS-TEST-123>>
- Resultado seguro: se muestra exactamente igual (con
<
y>
). - Señal de riesgo: se convierte en algo con formato o “clickable”.
4) Revisa emails y paneles internos
Si esos datos te llegan por email o aparecen en tu panel de gestión:
- Resultado seguro: se ven como texto plano.
- Señal de riesgo: aparecen con formato o “activos” (como si fueran parte de la web).
👉 Te recomendamos leer este artículo si te interesa ver un ejemplo para detectar si un correo es real.
Si algo falla, ¿qué hago?
- Pausa temporalmente el formulario o modéralo (que no se publique automáticamente).
- Avisa a tu proveedor y pide corrección prioritaria.
- Pregunta si ha habido accesos raros o datos expuestos.
- Documenta: qué pasó, cuándo, a quién afectó y qué medidas se toman (útil para RGPD).
Qué exigirle a tu proveedor
Pídeles estas 5 cosas por escrito y que te lo enseñen en una demo:
- “Mostrar como texto” lo que escriben los usuarios
Cómo verlo: repetir las pruebas de arriba y comprobar que se ven como texto. - CSP (Content-Security-Policy) básica
Cómo verlo: que la página no permita scripts “sueltos” escritos por usuarios; solo código propio. - Cookies de sesión protegidas
Cómo verlo: en una videollamada, que enseñen los atributos HttpOnly, Secure y SameSite en el navegador. - Limpieza si aceptan texto “con formato”
Cómo verlo: que muestren la librería de sanitización y la lista permitida de etiquetas/atributos. - Revisión de puntos críticos
Cómo verlo: listado de formularios, buscadores, parámetros de URL y paneles internos probados con los ejemplos anteriores.
Frase que puedes copiarles:
“Necesito que cualquier dato que aporte un usuario se muestre como texto, sin ejecutarse. Enseñadme en una demo que
<b>Prueba</b>
y<script>alert("XSS")</script>
aparecen como texto en listados, perfiles, buscadores, emails y paneles internos. Confirmad también una CSP activa y cookies de sesión con HttpOnly, Secure y SameSite.”
Mini rincón técnico (para tu equipo o proveedor)
No necesitas entenderlo a fondo; te sirve para pedirlo.
En servidor (ej. PHP), ‘escapar’ antes de mostrar:
phpCopiarEditarecho htmlspecialchars($datoDelUsuario ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
En el navegador, tratar como texto (no HTML):
jsCopiarEditar// Mal: inserta HTML “vivo”
elemento.innerHTML = userInput;
// Bien: lo trata como texto
elemento.textContent = userInput;
Buenas prácticas complementarias:
- Evitar
eval
,new Function
,document.write
yinnerHTML
con datos del usuario. - Activar una CSP (por ejemplo:
default-src 'self'; script-src 'self'; object-src 'none'
). - Cookies de sesión con HttpOnly; Secure; SameSite=Lax/Strict.
- Si aceptas HTML del usuario, usar sanitización con lista permitida (pide a tu equipo una librería fiable).
Checklist rápido para imprimir
- Mis formularios muestran texto tal cual (las pruebas se ven como texto, no como formato).
- Buscadores/filtros no “activan” lo que escribo.
- Emails y panel interno muestran texto plano.
- Hay CSP activa.
- Cookies de sesión con HttpOnly, Secure y SameSite.
- Si acepto texto con formato, hay sanitización con lista permitida.
- El proveedor me ha hecho una demo pasando estas pruebas.
No hace falta ser técnico para detectar señales claras de XSS. Con tres pruebas simples puedes saber si tu formulario muestra texto o ejecuta lo que le ponen.
Si ves algo raro, páralo, pide corrección y exige las garantías de arriba. Te ahorrarás sustos, costes y dolores de cabeza legales.