XSS guide
Guía sobre la vulnerabilidad XSS
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Explicación técnica de la vulnerabilidad XSS
. Detallamos cómo identificar
y explotar
esta vulnerabilidad, tanto manualmente
como con herramientas automatizadas
. Además, exploramos estrategias clave para prevenirla
¿Qué es un XSS?
La vulnerabilidad de Cross-site scripting (XSS)
es una vulnerabilidad de seguridad web
que permite a un atacante comprometer las interacciones
que los usuarios tienen con una aplicación vulnerable
. Permite evadir la política de mismo origen (same origin policy)
, diseñada para separar diferentes sitios web entre sí
Los ataques XSS
normalmente permiten que un atacante suplante la identidad de un usuario víctima
, realice cualquier acción
que este pueda ejecutar y acceda a sus datos
. Si el usuario afectado tiene privilegios elevados
dentro de la aplicación, el atacante podría hacerse con el control total
de toda su funcionalidad y datos
¿Para qué puede usarse XSS?
Un atacante que explota una vulnerabilidad de cross-site scripting
normalmente puede llevar a cabo estas acciones
Hacerse pasar por el usuario víctima
Realizar cualquier acción
que el usuario pueda ejecutarLeer cualquier dato
al que el usuario tenga accesoCapturar las credenciales de inicio de sesión
del usuarioHacer un
defacement
del sitio webInyectar un funcionalidad tipo troyano
en el sitio web
PoC de XSS
Podemos confirmar la mayoría de las vulnerabilidades
de XSS
inyectando un payload
que haga que nuestro propio navegador
ejecute algún JavaScript
arbitrario. Desde hace tiempo, es común usar la función alert()
para este propósito porque es corta
, inofensiva
y difícil de pasar por alto
cuando se ejecuta con éxito
Sin embargo, hay un inconveniente
si usamos Chrome
. A partir de la versión 92
, los cross-origin iframes
tienen prohibido llamar a alert()
y como estos se utilizan para construir algunos de los ataques XSS
más avanzados
, a veces debemos usar un payload
alternativo de PoC
. Es por esto, que se se recomienda la función print()
Contexto
A la hora de testear un reflected XSS
o stored XSS
, un paso clave es identificar
el contexto
, para ello, lo primero que necesitamos saber es dónde se refleja nuestro input
. Existen estos tipos de contexto
:
XSS entre etiquetas HTML
XSS dentro de los atributos de etiquetas HTML
XSS dentro de código JavaScript
Finalizar el script existente
Escapar de una string
Hacer uso de HTML-encoding
Inyectar expresiones de JavaScript en template literals
Tipos de ataques XSS
Existen tres tipos principales de ataques XSS:
Reflected XSS
– Ocurre cuando losdatos proporcionados por el usuario
se incluyen inmediatamente en larespuesta del servidor
sin lavalidación
oescape
adecuadosStored XSS
– Sucede cuando losdatos maliciosos
enviados por el usuario sealmacenan en el servidor
(por ejemplo, en unabase de datos
) y luego se sirven a otros usuarios sin lasanitización
adecuadaDOM Based XSS
– Este tipo devulnerabilidad
se origina en ellado del cliente
, donde elcódigo JavaScript
manipula de forma insegura elDOM de la web
, permitiendo la ejecución descripts maliciosos
Reflected XSS
Reflected XSS into HTML context with nothing encoded - https://justice-reaper.github.io/posts/XSS-Lab-1/ (XSS entre etiquetas HTML)
Reflected XSS into attribute with angle brackets HTML-encoded - https://justice-reaper.github.io/posts/XSS-Lab-7/ (XSS dentro de los atributos de etiquetas HTML)
Reflected XSS into a JavaScript string with angle brackets HTML encoded - https://justice-reaper.github.io/posts/XSS-Lab-9/ (XSS dentro de código JavaScript - Escapar de una string)
Reflected XSS into HTML context with most tags and attributes blocked - https://justice-reaper.github.io/posts/XSS-Lab-14/ (XSS entre etiquetas HTML)
Reflected XSS into HTML context with all tags blocked except custom ones - https://justice-reaper.github.io/posts/XSS-Lab-15/ (XSS entre etiquetas HTML)
Reflected XSS with some SVG markup allowed - https://justice-reaper.github.io/posts/XSS-Lab-16/ (XSS entre etiquetas HTML)
Reflected XSS in canonical link tag - https://justice-reaper.github.io/posts/XSS-Lab-17/ (XSS dentro de los atributos de etiquetas HTML)
Reflected XSS into a JavaScript string with single quote and backslash escaped - https://justice-reaper.github.io/posts/XSS-Lab-18/ (XSS dentro de código JavaScript - Finalizar el script existente)
Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped - https://justice-reaper.github.io/posts/XSS-Lab-19/ (XSS dentro de código JavaScript - Escapar de una string)
Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped - https://justice-reaper.github.io/posts/XSS-Lab-21/ (XSS dentro de código JavaScript - Inyectar expresiones de JavaScript en template literals)
Stored XSS
Stored XSS into HTML context with nothing encoded - https://justice-reaper.github.io/posts/XSS-Lab-2/ (XSS entre etiquetas HTML)
Stored XSS into anchor href attribute with double quotes HTML-encoded - https://justice-reaper.github.io/posts/XSS-Lab-8/ (XSS dentro de los atributos de etiquetas HTML)
Stored XSS into onclick event with angle brackets and double quotes HTML-encoded and single quotes and backslash escaped - https://justice-reaper.github.io/posts/XSS-Lab-20/ (XSS dentro de código JavaScript - Hacer uso de HTML-encoding)
Dom Based XSS
DOM XSS in document.write sink using source location.search - https://justice-reaper.github.io/posts/XSS-Lab-3/
DOM XSS in innerHTML sink using source location.search - https://justice-reaper.github.io/posts/XSS-Lab-4/
DOM XSS in jQuery anchor href attribute sink using location.search source - https://justice-reaper.github.io/posts/XSS-Lab-5/
DOM XSS in jQuery selector sink using a hashchange event - https://justice-reaper.github.io/posts/XSS-Lab-6/
DOM XSS in document.write sink using source location.search inside a select element - https://justice-reaper.github.io/posts/XSS-Lab-10/
DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded - https://justice-reaper.github.io/posts/XSS-Lab-11/
Reflected DOM XSS - https://justice-reaper.github.io/posts/XSS-Lab-12/
Stored DOM XSS - https://justice-reaper.github.io/posts/XSS-Lab-13/
Sinks que pueden conducir a vulnerabilidades de tipo DOM XSS
Los siguientes son algunos de los principales sinks
que pueden provocar vulnerabilidades de tipo DOM XSS
1
2
3
4
5
6
7
document.write()
document.writeln()
document.domain
element.innerHTML
element.outerHTML
element.insertAdjacentHTML
element.onevent
Las siguientes funciones de jQuery algunas de los principales sinks
que pueden provocar vulnerabilidades de tipo DOM XSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
add()
after()
append()
animate()
insertAfter()
insertBefore()
before()
html()
prepend()
replaceAll()
replaceWith()
wrap()
wrapInner()
wrapAll()
has()
constructor()
init()
index()
jQuery.parseHTML()
$.parseHTML()
Explotar vulnerabilidades XSS
La forma tradicional
de demostrar que hemos encontrado una vulnerabilidad de cross-site scripting
es crear un popup
usando la función alert()
. Esto no es porque el XSS
tenga algo que ver con los popups, es simplemente una forma de demostrar que podemos ejecutar código JavaScript arbitrario
en un dominio dado
. Puede que notes que algunas personas usan alert(document.domain)
. Esto sirve para dejar explícito
en qué dominio
se está ejecutando el JavaScript
Para demostrar que una vulnerabilidad XSS
es una amenaza real
proporcionando un exploit completo
. En esta sección exploraremos tres de las formas más populares
de explotar
un XSS
Robar cookies
Robar cookies
es una forma tradicional
de explotar XSS
. La mayoría de las aplicaciones web
usan cookies
para el manejo de sesiones
. Podemos explotar
vulnerabilidades de cross-site scripting
para enviar las cookies de la víctima
a nuestro propio dominio
, luego inyectar manualmente las cookies
en el navegador y suplantar a la víctima
En la práctica, este método tiene algunas limitaciones importantes
:
La víctima podría no estar
logueada
Muchas aplicaciones ocultan sus
cookies
de JavaScript usando laflag HttpOnly
Las
sesiones
pueden estarvinculadas
a factores adicionales, como ladirección IP del usuario
La
sesión
puedeexpirar
antes de que podamossecuestrarla
En este laboratorio
podemos ver como aplicar
esta técnica
:
- Exploiting cross-site scripting to steal cookies - https://justice-reaper.github.io/posts/XSS-Lab-22/
Capturar contraseñas
Hoy en día, muchos usuarios tienen gestores de contraseñas
que autocompletan
sus contraseñas. Podemos aprovechar esto creando un campo de contraseña
, leyendo la contraseña autocompletada
y enviándola a nuestro propio dominio
. Esta técnica evita la mayoría de los problemas asociados con robar cookies
y puede incluso obtener acceso
a todas las demás cuentas donde la víctima haya reutilizado la misma contraseña
La principal desventaja
de esta técnica es que solo funciona con usuarios que tienen un gestor de contraseñas
que realiza autocompletado
. Si un usuario no tiene guardada una contraseña, podemos intentar obtenerla mediante un ataque de phishing
En este laboratorio
podemos ver como aplicar
esta técnica
:
- Exploiting cross-site scripting to capture passwords - https://justice-reaper.github.io/posts/XSS-Lab-23/
Bypassear las protecciones contra CSRF
Un XSS
permite a un atacante hacer casi todo lo que un usuario legítimo
puede hacer en un sitio web
. Al ejecutar código JavaScript arbitrario
en el navegador de la víctima, el XSS
nos permite realizar una amplia variedad de acciones como si fuéramos ese usuario. Por ejemplo, podemos hacer que la víctima envíe
un mensaje
, acepte
una solicitud de amistad
o transfiera
algunos Bitcoins
Algunos sitios web
permiten a los usuarios logueados
cambiar su dirección de correo electrónico
sin volver a ingresar
su contraseña
. Si encontramos un XSS
en uno de estos sitios web, podemos explotarlo para robar un token CSRF
. Con ese token
, podemos cambiar el correo electrónico
de la víctima
a una que controlemos
. Luego, podemos activar un restablecimiento de contraseña
para obtener acceso a la cuenta
Este tipo de exploit
combina XSS
(para robar el token CSRF
) con la funcionalidad normalmente atacada por CSRF
. Mientras que el CSRF tradicional
es una vulnerabilidad de “una sola vía”, donde el atacante
puede inducir
a la víctima
a enviar peticiones
pero no puede ver las respuestas
, el XSS
permite una comunicación bidireccional
. Esto permite al atacante tanto enviar peticiones
como leer las respuestas
, resultando en un ataque híbrido que evade las defensas anti-CSRF
En este laboratorio
podemos ver como aplicar
esta técnica
:
- Exploiting XSS to bypass CSRF defenses - https://justice-reaper.github.io/posts/XSS-Lab-24/
¿Cómo detectar y explotar un XSS?
Es posible detectar XSS
de varias formas, en mi caso sigo estos pasos:
Añadir
eldominio
y sussubdominios
alscope
Hacer un
escaneo general
conBurpsuite
. Comotipo de escaneo
marcaremosCrawl and audit
y comoconfiguración de escaneo
usaremosDeep
Escanearemos partes específicas de la petición
usando elescáner de Burpsuite
. Paraescanear
losinsertion points
debemos seleccionar entipo de escaneo
la opciónAudit selected items
Con el objetivo de encontrar
vulnerabilidades
de tipoDOM XSS
usamos elDOM Invader
para testear todos losinputs
Una vez hecho esto, usamos
XSStrike
con el parámetro--crawl
para poderidentificar
si hay algunavulnerabilidad
o algúnsink
, el cual pueda conducir a unXSS
Usamos
XSStrike
nuevamente, pero esta vez con el objetivo dedetectar
unXSS
Si no encontramos nada y la
URL
es de este estilohttps://0a42008c0326fbeb803d129600e6006e.web-security-academy.net/?search=test
o de este otrohttp://stock.0a1b001e03ee4b4480f30dd1005a0015.web-security-academy.net/?productId=3&storeId=1
, vamos a usarLoxs
yXSSuccessor
Si
Loxs
yXSSuccessor
no encuentran nada, podemos usarDalfox
, el cual tiene soporte paraDOM XSS
,Reflected XSS
yStored XSS
. Además, cuenta con lospayloads
dePayloadBox
yPortswigger
para descubrirXSS
. También cuenta con losdiccionarios
deBurpsuite
yAssetnote
para descubrirparámetros
en la URL vulnerables aXSS
. Desde mi experiencia, esta herramienta no me ha dado muy buenos resultados, pero podemosprobar
a ver siencuentra algo
o usar el comandodalfox payload -h
para listar varias opciones que nos permitirán ver lospayloads
que usaDalfox
y usarlos con otrasherramientas
. Por ejemplo, con elIntruder
deBurpsuite
, aunquepuede ser complicado encontrar el payload correcto si mandamos muchos a la vez
. Por eso, recomiendo usar la herramientaPayloadSplitter
https://github.com/Justice-Reaper/PayloadSplitter.git paradividir
unagran lista de payloads
enlistas más pequeñas y manejables
Si sospechamos de un
stored XSS
, usaremos lospaylods
deLoxs
,XSSuccessor
o los deDalfox
con elIntruder
deBurpsuite
y seleccionaremosPitchfork
como tipo de ataqueEn el caso en que haya algunos
tags
oatributos
blacklisteados, podemos usarXSSDynaGen
o elfuzzer de XSStrike
para ver quecaracteres
podemos usar. Sin embargo, yo prefiero usar elIntruder
deBurpsuite
junto con lacheatsheet de Portswigger
para averiguarlo, debido a que esta forma es másprecisa
Si no encontramos nada, nos centraremos en buscar los
XSS de forma manual
utilizando la metodología deHacktricks
y usando como apoyo lascheatsheets
dePortswigger
y dePayloadsAllTheThings
En el caso de que sospechemos de un
Blind XSS
, podemos usar variasherramientas
paraidentificarlo
. Si disponemos de unVPS
, podemos usarXSSHunter Express
y si no disponemos de uno, podemos usarXXHunter
,BXSSHunter
oXSSReport
Cheatsheets para XSS
En Hacktricks
tenemos una metodología
para encontrar XSS
y explotarlos
. En Portswigger
tenemos diferentes payloads
que, combinados con Burpsuite
, nos permiten identificar
qué tags
y eventos
están permitidos
y de esta forma construir un payload válido
. En PayloadsAllTheThings
tenemos payloads
que podemos usar
y herramientas recomendadas
Hacktricks https://book.hacktricks.wiki/en/pentesting-web/xss-cross-site-scripting/index.html
Portswigger https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
PayloadsAllTheThings https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection
Herramientas
Tenemos estas herramientas
para automatizar
la explotación
de XSS
:
XSSDynaGen https://github.com/Cybersecurity-Ethical-Hacker/xssdynagen.git
XSSuccessor https://github.com/Cybersecurity-Ethical-Hacker/xssuccessor.git
XSSHunter Express https://github.com/mandatoryprogrammer/xsshunter-express.git
BXSSHunter https://bxsshunter.com/
XSSReport https://xss.report/
DOM Invader https://portswigger.net/burp/documentation/desktop/tools/dom-invader
Prevenir ataques XSS
La prevención de XSS
puede lograrse, en general, mediante dos capas de defensa
:
Codificar
losdatos
en lasalida
Validar
elinput de datos
alrecibirlo
La codificación
debe aplicarse justo antes de que los datos controlados por el usuario
se escriban en una página
, porque el contexto
en el que se escriben determina el tipo de codificación
que debemos usar. Por ejemplo, los valores
dentro de una cadena JavaScript
requieren un tipo de escapado
diferente al de un contexto HTML
En un contexto HTML
, debemos convertir los valores no permitidos
en entidades HTML
<
se convierte en:<
>
se convierte en:>
En un contexto de cadena JavaScript
, los valores no alfanuméricos
deben escaparse en Unicode
<
se convierte en:\u003c
>
se convierte en:\u003e
A veces, debemos aplicar múltiples capas de codificación
, en el orden correcto
. Por ejemplo, para incrustar de forma segura
el input del usuario
dentro de un manejador de eventos
, debemos tratar tanto el contexto JavaScript
como el contexto HTML
. En este caso, primero debemos escapar en Unicode
el input
y luego codificarlo en HTML
1
<a href="#" onclick="x='This string needs two layers of escaping'">test</a>
Validar el input al recibirlo
La codificación
probablemente sea la línea de defensa más importante
contra XSS
, pero no es suficiente para prevenir vulnerabilidades
en todos los contextos
. También debemos validar el input
de la forma más estricta posible
en el momento en que se recibe por primera vez del usuario
Ejemplos de validación de input
:
Si un
usuario
envía unaURL
que se devolverá en lasrespuestas
, validar queempiece con un protocolo seguro
comoHTTP
oHTTPS
. De lo contrario, alguien podríaexplotar el sitio
usando un protocolo peligroso comojavascript
odata
Si un
usuario
proporciona unvalor
que se espera seanumérico
, validar que el valor contenga realmente unentero
Validar que el
input
solo contenga unconjunto de caracteres esperado
La validación del input
debería funcionar bloqueando
el input no válido
. La alternativa que consiste en intentar limpiar el input inválido
para hacerlo válido, es más propensa a errores
y debe evitarse siempre que sea posible
Whitelisting vs Blacklisting
La validación de input
debe usar preferiblemente whitelists
en lugar de blacklists
. Por ejemplo, en lugar de intentar crear
una lista
con todos los protocolos peligrosos
(javascript
, data
, etc.), debemos hacer una lista con los protocolos seguros
(HTTP
, HTTPS
) y bloquear
todo lo que no esté en la lista
. Esto asegura que la defensa no falle cuando aparezcan nuevos protocolos peligrosos
y reduce el riesgo frente a ataques que intenten ofuscar valores inválidos
para evadir la blacklist
Permitir HTML “seguro”
Permitir que los usuarios publiquen HTML
debería evitarse
siempre que sea posible, aunque a veces es un requisito de negocio
. Por ejemplo, un blog
podría permitir que los comentarios
contengan HTML limitado
El enfoque clásico es intentar filtrar
las etiquetas peligrosas
y JavaScript
. Podemos implementar esto usando una whitelist
de etiquetas
y atributos seguros
, pero debido a las diferencias en los motores de parseo de navegadores
y a técnicas como mutation XSS
, este método es extremadamente difícil de implementar de forma segura
La opción menos mala
es usar una librería JavaScript
que realice el filtrado
y la codificación
en el navegador del usuario
, como DOMPurify
. Otras librerías permiten que los usuarios escriban en Markdown
y luego lo convierten a HTML
. Sin embargo, todas estas librerías tienen vulnerabilidades XSS
de vez en cuando, por lo que no es una solución perfecta
. Por lo tanto, si usamos una, debemos vigilar de cerca
las actualizaciones de seguridad
Además de JavaScript
, CSS
e incluso HTML
pueden ser peligrosos
en algunas situaciones https://portswigger.net/research/detecting-and-exploiting-path-relative-stylesheet-import-prssi-vulnerabilities#badcss
Prevenir XSS usando un motor de plantillas
Muchos sitios web modernos usan motores de plantillas del lado del servidor
como Twig
o Freemarker
para incrustar contenido dinámico
en HTML
. Estos suelen tener su propio sistema de escapado
, por ejemplo, en Twig
podemos usar el filtro e()
con un argumento que define el contexto
1
Otros motores de plantillas, como Jinja
o React
, escapan el contenido dinámico por defecto
, lo que previene la mayoría de los casos de XSS
. Se recomienda revisar cuidadosamente
las funciones de escapado
al evaluar si usar un motor de plantillas
o framework
concreto
Si se concatena directamente
el input del usuario
en templates strings
, nos volvemos vulnerables
a SSTI (Server-Side Template Injection)
, que a menudo es más grave
que el XSS
Prevenir XSS en PHP
En PHP
existe la función incorporada htmlentities
para codificar entidades
. Debemos llamarla para escapar el input
cuando estemos en un contexto HTML
. Debe llamarse con tres argumentos:
El
input
ENT_QUOTES
, una bandera que indica que se deben codificar todas lascomillas
El
conjunto de caracteres
, que normalmente debe serUTF-8
1
<?php echo htmlentities($input, ENT_QUOTES, 'UTF-8');?>
En un contexto de cadena JavaScript
, debemos escapar en Unicode
el input
. Desafortunadamente, PHP
no incluye una API para hacer Unicode-escape
a un string
. Así se puede implementar manualmente en PHP
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
function jsEscape($str) {
$output = '';
$str = str_split($str);
for ($i = 0; $i < count($str); $i++) {
$chrNum = ord($str[$i]);
$chr = $str[$i];
// Manejo de caracteres especiales Unicode (U+2028, U+2029)
if ($chrNum === 226) {
if (isset($str[$i+1]) && ord($str[$i+1]) === 128) {
if (isset($str[$i+2]) && ord($str[$i+2]) === 168) {
$output .= '\u2028';
$i += 2;
continue;
}
if (isset($str[$i+2]) && ord($str[$i+2]) === 169) {
$output .= '\u2029';
$i += 2;
continue;
}
}
}
// Escapado de caracteres especiales
switch ($chr) {
case "'":
case '"':
case "\n":
case "\r":
case "&":
case "\\":
case "<":
case ">":
$output .= sprintf("\\u%04x", $chrNum);
break;
default:
$output .= $str[$i];
break;
}
}
return $output;
}
?>
Así se usa la función jsEscape
en PHP
1
<script>x = '<?php echo jsEscape($_GET['x'])?>';</script>
Alternativamente
, podríamos usar un motor de plantillas
Prevenir XSS del lado del cliente en JavaScript
Para escapar el input del usuario
en un contexto HTML
en JavaScript
, necesitamos un codificador HTML propio
porque JavaScript no proporciona una API para codificar HTML
. Esta función
de JavaScript
convierte una cadena en entidades HTML
1
2
3
4
5
6
function htmlEncode(str) {
return String(str)
.replace(/[^\w. ]/gi, function(char) {
return '&#' + char.charCodeAt(0) + ';';
});
}
Podríamos usar la función anterior
así:
1
<script>document.body.innerHTML = htmlEncode(untrustedValue)</script>
Si el input
está dentro de una cadena JavaScript
, necesitaremos un codificador
que realice el escape de los caracteres en Unicode
. Este sería un ejemplo
:
1
2
3
4
5
function jsEscape(str) {
return String(str).replace(/[^\w. ]/gi, function(c) {
return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);
});
}
Podríamos usar la función anterior
así:
1
<script>document.write('<script>x="'+jsEscape(untrustedValue)+'";<\/script>')</script>
Prevenir XSS en jQuery
La forma más común de XSS
en jQuery
ocurre cuando pasamos el input
del usuario
a un selector de jQuery
. Los desarrolladores web
a menudo usaban location.hash
y lo pasaban al selector
, lo que causaba un XSS
porque jQuery
interpretaba ese contenido como HTML
jQuery
reconoció este problema y corrigió
la lógica del selector
para verificar
si el input
comienza con un símbolo de hash (#)
. Ahora, jQuery solo renderiza HTML
si el primer carácter es un <
Si le pasamos datos no confiables
al selector de jQuery
, debemos asegurarnos de escapar correctamente
el valor
usando la función jsEscape
Mitigación de XSS usando la política de seguridad de contenido (CSP)
La política de seguridad de contenido (CSP)
es la última línea de defensa
contra el cross-site scripting
. Si la prevención de XSS falla
, podemos usar CSP para mitigar XSS
restringiendo lo que un atacante puede hacer
CSP
permite controlar varias cosas, por ejemplo, si se pueden cargar scripts externos
y si se ejecutarán inline scripts
. Para desplegar CSP, necesitaremos incluir un encabezado HTTP
llamado Content-Security-Policy
con un valor que contenga tu política
Un ejemplo
de CSP
sería este:
1
default-src 'self'; script-src 'self'; object-src 'none'; frame-src 'none'; base-uri 'none';
Esta política
especifica que los recursos
, como imágenes
y scripts
, solo pueden cargarse desde el mismo origen
que la página principal. Por lo tanto, aunque un atacante logre inyectar un payload XSS
, solo podrá cargar recursos desde el origen actual
. Esto reduce significativamente
la posibilidad de que un atacante pueda explotar
el XSS
Si necesitamos cargar recursos externos
, debemos asegurarnos de permitir solo scripts
que no ayuden al atacante a explotar
nuestro sitio web
. Por ejemplo, si permitimos explícitamente ciertos dominios
, un atacante podría cargar cualquier script desde esos dominios. Siempre que sea posible, debemos alojar los recursos en nuestro propio dominio
Si eso no es posible, podemos usar una política basada en hash o nonce
para permitir scripts en diferentes dominios
. Un nonce
es una cadena aleatoria
que se añade como atributo
a un script
o recurso
, y solo se ejecutará si esa cadena coincide con la generada por el servidor
. Un atacante no puede adivinar esa cadena aleatoria, por lo que no podrá ejecutar
un script
o recurso
con un nonce válido