Shikata Ga Nai

Private? There is no such things.

A $$$ worth of cookies! | Reflected DOM-Based XSS | Bug Bounty POCを訳してみた

Hello there, ('ω')ノ

 

$$$相当のクッキー! | 反映された DOM ベース XSS | バグ報奨金 POCを。

 

脆弱性:

 DOMベースXSS

 

記事:

 https://medium.com/@haroonhameed_76621/a-775-worth-of-cookies-reflected-dom-based-xss-bug-bounty-poc-3e7720c78fbe

 

今回は、リフレクトされた DOM ベースの XSS に関する Synack Red チームでの

最近の発見について。

それは Synack Red Team の QR ベースのターゲットで。

 

脆弱性分析:

主な焦点はメイン ドメイン (https://redacted.com) で。

そのため、サブドメインの列挙は行わず、

魅力的な JavaScript ファイルを探し始めて。

幸運なことに、興味深い JavaScript ファイルを 2 つ見つけて。

 

code: function(e) {
                    var a = e.car,
                        t = e.articleUuid,
                        i = e.returnPath,
                        u = e.moreInfoData,
                        m = e.currentUser,
                        o = m.canPrint,
                        d = void 0 === o || o,
                        E = m.canBookmark,
                        b = void 0 === E || E,
                        f = a.uuid,
                        h = i ? "Search Results" : "Car";
                    return l.createElement("div", null, l.createElement("div", {
                        className: "viewer-header"
                    }, l.createElement("div", {
                        className: "car-form-container"
                    }, l.createElement("div", {
                        className: "article-toolbar-container"
                    }, l.createElement("div", {
                        className: "page-width article-toolbar"
                    }, l.createElement(l.Suspense, {
                        fallback: l.createElement("div", null)
                    }, l.createElement(s, a)), l.createElement("ul", {
                        className: "back-to-search-ul"
                    }, l.createElement("li", {
                        className: "back-to-search-results"
                    }, l.createElement("a", {
                        className: "button",
                        href: i || "/car/" + f + "/search"
                    },

 

----------

この処理は、与えられた引数 e を解析し、その値に基づいて

React コンポーネントを生成していて。

 

以下は処理の概要:

1.e オブジェクトから必要な値を取得します。

 具体的には、e.car、e.articleUuid、e.returnPath、e.moreInfoData、e.currentUser を取得しています。

2.取得した値をそれぞれ変数に代入します。

 a には e.car、t には e.articleUuid、i には e.returnPath、u には e.moreInfoData、

 m には e.currentUser の値が代入されます。

3.m オブジェクトから canPrint と canBookmark の値を取得し、

 それぞれ o と E に代入します。

 もし値が未定義(undefined)だった場合は、

 デフォルト値として true が代入されます。

4.a.uuid の値を f に代入します。

5.条件に基づいて変数 h に文字列を代入します。

 もし i が truthy(真の値)であれば、h には "Search Results" が代入されます。

 そうでなければ、h には "Car" が代入されます。

6.React のコンポーネントを生成します。

 最初の <div> タグは親要素となります。

7.<div className="viewer-header"> の中にヘッダー部分のコンポーネントを

 生成します。

8.ヘッダー内部にはさらに <div className="car-form-container">、

 <div className="article-toolbar-container">、

 <div className="page-width article-toolbar"> のコンポーネントが生成されます。

9.l.Suspense コンポーネントが使われており、fallback プロパティには

 ローディング中に表示する要素が指定されています。

10.<s> コンポーネントが生成され、a が props として渡されます。

11.<ul className="back-to-search-ul"> の中には

 <li className="back-to-search-results"> が生成されます。

12.<a className="button"> が生成され、href プロパティには i の値か、

 もしくは /car/ + f + /search の文字列が指定されます。

----------

 

このコードは、React アプリケーションでカー ビューアー コンポーネントを

レンダリングするために使用され。

このコンポーネントには、車の詳細のほか、検索に戻るボタンやユーザが

特定のアクションを実行できるツールバーなどの他の情報が表示され。

 

「a」タグの href 属性が適切にサニタイズされていない場合

このコードで DOM ベースの XSS が可能になり。

ユーザ入力が適切にサニタイズされていない場合、悪意のあるコードが実行され、

DOM ベースの XSS 攻撃が可能になる可能性があり。

 

2 番目の JavaScript ファイルで、反映された DOM ベース XSS の適切なソースと

シンクが見つかり。

以下がソースとシンクで。

 

ソース:

document.addEventListener("DOMContentLoaded", (function() {
            var e = document.getElementById("search-application-container")
              , t = JSON.parse(e.getAttribute("state")) || window.initialState;
            a.render(r.createElement(rr, t), e)

 

このソースは、DOM で React コンポーネントをレンダリングするために

使用され。

ID「search-application-container」を持つ要素から状態を解析し、

それを React コンポーネントに渡し。

次に、コンポーネントが要素内にレンダリングされて。

 

シンク:

l.createElement("a", {
                        className: "button",
                        href: i || "/car/" + f + "/search"
                    }

 

DOM 関数 l.createElement は HTML タグを作成し、

その属性値をユーザが制御可能な returnPath パラメータである HTML href 属性に

設定して。

 

JavaScript コードを理解すると、returnPath パラメータからユーザ指定の

入力を受け取り、それを DOM 別名シンクで実行することが明確にわかり。

そこで、次の JavaScript ペイロードを使用して。

 

 javascript:alert(document.domain)

 

 

Best regards, (^^ゞ