Shikata Ga Nai

Private? There is no such things.

Little bug, Big impact. 25k bountyを訳してみた

Hello there, ('ω')ノ

 

小さなバグ、大きな影響を。

 

脆弱性:

 ハードコードされた API キー

 

記事:

 https://blog.prodefense.io/little-bug-big-impact-25k-bounty-9e47773f959f

 

序章:

有名企業の Web アプリケーションの脆弱性を探していて。

コードを何度もスキャンしましたが、何かがおかしいと感じ。

そこで、アプリケーションのフロントエンドで実行されている JavaScript を

詳しく調べることにして。

 

さらに掘り下げていくと、Stripe を介して支払いを処理するために使用されていた

ハードコードされた機密データの宝庫に出くわし。

問題の秘密は、Stripe API の公開可能な鍵と秘密鍵そのもので。

これらのキーはアプリケーションのフロントエンドに保存されていたため、

悪意のある人が簡単に選択できるようになっていて。

 

最も驚いたのは、これらの秘密には、スキャナやツールで簡単に

検出できる一般的な名前がなかったことで。

これらは JavaScript 内に巧妙に隠され、検出が困難で。

しかし、経験と専門知識により、それらを発見し、

すぐに会社に警告することができて。


JavaScript ソース マッピング


実際のウェブサイトではなく、単なる例で。

JavaScript ソース マッピングは、縮小された JavaScript ファイルのコードを

元のソース コードにマップし。

これはデバッグに役立ち、開発者はエラーの原因を簡単に見つけることができて。

縮小すると、コメント、関数名、変数名などの情報が削除され、

デバッグが難しくなり。

縮小されたファイルと一緒にソース マップが生成され、

コンパイルされたコードが元のコードにマッピングされ、

コンパイルされたコードでエラーが発生したときに、

ブラウザーがより役立つエラー メッセージを表示できるようになって。

 

開発とデバッグには便利ですが、API キーやパスワードなどのシークレットが

元のソース コードに含まれている場合、ソース マップは

セキュリティ リスクをもたらす可能性もあり。

 

この情報はソース マップを介して公開される可能性があり、

機密リソースへの不正アクセスが可能になり。

その結果、JavaScript コードにシークレットを含めることを避け、

代わりに安全なストレージまたは環境変数を使用することが不可欠で。

また、ソース マップ内の機密情報を公開する可能性のあるコメントや

データをビルド プロセスで確実に削除することも必要で。


バグを見つけるために

SourceMapper ツール を使用して、縮小された JavaScript を

より読みやすいバージョンに再構築することができて。

 

https://github.com/denandz/sourcemapper

 

このツールの使用方法の例を以下に。

 

doi@asov:~$ ./sourcemapper -output dhubsrc -url https://hub.docker.com/public/js/client.356c14916fb23f85707f.js.map
[+] Retriving Sourcemap from https://hub.docker.com/public/js/client.356c14916fb23f85707f.js.map
[+] Read 23045027 bytes, parsing JSON
[+] Retrieved Sourcemap with version 3, containing 1828 entries
[+] Writing 9076765 bytes to dhubsrc/webpack:/js/client.356c14916fb23f85707f.js
[+] Writing 1014 bytes to dhubsrc/webpack:/webpack/bootstrap 356c14916fb23f85707f
[+] Writing 3174 bytes to dhubsrc/webpack:/app/scripts/client.js
[+] Writing 281 bytes to dhubsrc/webpack:/~/babel-runtime/helpers/interop-require-default.js
[+] Writing 151 bytes to dhubsrc/webpack:/~/babel-core/polyfill.js
{snip}

 

コードが読み取り可能な形式になると、JavaScript を検索して

次のコードを見つけるまでに数分かかり。

 

export const S0 = 'pk_live_[REDACTED]es33';
export const S1 = 'sk_live_[REDACTED]du8d';
export const STRIPE_HEADER_NAME = 'REDACTED';
export const CURRENCY = 'USD';
export const STRIPE_PAY_BUTTON = 'Pay for REDACTED';

 

それが秘密のAPIキーで。

Stripe には、このアカウントの残高を確認したり、別のアカウントに

送金したりできる非常に便利な API があり。

 

❯ curl https://api.stripe.com/v1/balance -u sk_live_REDACTEDdu8d
{"object": "balance",
 "available": [ {
 "amount": 1761520.76,
 "currency": "usd",
 "source_types": {
 "card": 0 } } ]
}

 

Best regards, (^^ゞ