Prevención de XSS

A estas alturas ya sabemos:

Ahora toca la parte defensiva: cómo prevenir XSS correctamente.


🧠 Idea clave

Una vulnerabilidad XSS siempre involucra dos elementos:

👉 Para prevenir XSS hay que proteger ambos, tanto en front-end como en back-end.


🖥️ Prevención en Front-end

El front-end es donde se recibe la mayoría de entradas del usuario, por lo que validar y sanear aquí reduce riesgos, pero nunca es suficiente por sí solo.


✅ Validación de entrada

La validación asegura que los datos tienen el formato esperado.

Ejemplo: validación de email con JavaScript

function validateEmail(email) {
    const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}

📌 Esto evita entradas inválidas pero no detiene XSS por sí solo.


🧼 Sanitización de entrada

La sanitización elimina o neutraliza código peligroso.

Una librería estándar es DOMPurify:

<script src="dist/purify.min.js"></script>
let clean = DOMPurify.sanitize(dirty);

📌 Esto elimina etiquetas <script>, eventos onerror, onclick, etc.


⛔ Entrada directa peligrosa

Nunca insertar directamente input del usuario en:

Ejemplo peligroso:

<div name="INPUT_USUARIO"></div>

🚫 Funciones JavaScript peligrosas

Evitar usar input del usuario con:

Y en jQuery:

📌 Todas escriben HTML crudo, ideal para XSS.


🗄️ Prevención en Back-end

El back-end es la defensa real. Todo lo del front-end puede ser bypassed.


✅ Validación de entrada en Back-end

Ejemplo en PHP:

if (filter_var($_GET['email'], FILTER_VALIDATE_EMAIL)) {
    // procesar
} else {
    // rechazar entrada
}

📌 Si no cumple el formato esperado → no se procesa ni se muestra.


🧼 Sanitización de entrada en Back-end

Nunca mostrar input del usuario sin sanear.

Ejemplo en PHP:

addslashes($_GET['email']);

Ejemplo en NodeJS con DOMPurify:

import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(dirty);

🔐 Codificación de salida (Output Encoding)

Convierte caracteres peligrosos en entidades HTML.

Ejemplo PHP:

htmlentities($_GET['email']);

Ejemplo NodeJS:

import encode from 'html-entities';
encode('<'); // &lt;

📌 El navegador muestra el texto sin ejecutarlo.


⚙️ Configuración del servidor

Medidas adicionales muy importantes:

📌 HttpOnly evita session hijacking por XSS.


🧱 Protección por frameworks

Muchos frameworks incluyen protección XSS:

⚠️ Aun así, pueden existir fallos de lógica.


🧠 Conclusión

No existe una única defensa mágica contra XSS.

La protección real se basa en:

👉 Incluso con todo esto, siempre hay que pensar como atacante.

La mejor defensa es conocer bien el ataque.


🧪 Mentalidad de seguridad

Practicar:

Es la única forma de alcanzar un nivel realmente sólido frente a XSS.