DEV Community

Cover image for How I read react websites unminified source code through source maps
Raphaël Badia
Raphaël Badia

Posted on

How I read react websites unminified source code through source maps

Have you ever heard about source maps ?

They are the files that link minified js files to the original source file, allowing the browser to show you where the error is in the debugger.
It’s very useful for development purpose but can also be used in production to track bugs down.
And as this article says, it can also expose the source code of some websites, enabling other developers to learn by reading your codebase !

So, can we find some source map file available on google ? Google dorks makes it easy to find out. Let’s type ext:map. A lot of false positives… ext:map intext:webpack intext:react is way better but it returns a lot of results from git hosts such as GitHub and gitlab.



ext:map intext:webpack intext:react -site:github.com -intitle:GitLab -inurl:(git|blob|repo|browse)


Enter fullscreen mode Exit fullscreen mode

Better. That leaves us with a lot of sourcemaps to explore ! Let’s download a random on, I chose this one : CleanShot 2020-05-23 at 18.24.54@2x.png
To download a sourcemap file, you only need to click on it and save it as a .map.

To extract the source code from the source map, we are going to use a package called source-map-unpack. Unfortunately, some dependencies are outdated so we need to either install it with and old nodes version. You can do that with nvm : nvm use v10.20.1. If you don't have nvm, you can clone the repository, remove the ascii-progress dependency just like this and npm install. Then, running npx source-map-unpack ancestry ~/Downloads/landing-bundle.js-485a22ea.map (or npm start ancestry ./path/to/source/file.map if you cloned the repository) will create a folder ancestry containing the source code !

CleanShot 2020-05-23 at 18.31.15@2x.png
A preview of the folder created by source-map-unpack

We can see actions, reducers, components... It's an app using redux !
This doesn't seems like a full app, and the sourcemap filename (landing-bundle.js-485a22ea.map) made me think it was a single page. After some digging, I found I was reading the source code for https://www.ancestry.com/learn/facts :

CleanShot 2020-05-23 at 18.49.20.gif
A demonstration of the /learn/facts page behavior next to the extracted source code

When things get serious

Later, I stumbled on an interesting bundle name: app.js.map. It was 4 mb large, which I thought could be a more complete app. And gosh, what I got was way more interesting than the previous source map : I was looking at the source of the whole client dashboard of an energy company !

CleanShot 2020-05-23 at 18.03.53@2x.png

I learned some interesting things and saw good practices by skimming through their code, but also some weird things (they were abusively using refs and document.querySelector). And they had two useState() in total. The rest was class component.

Learning from others code is really interesting and you should definitely go take a look. There are a lot of US government open data sourcemap out there.

CleanShot 2020-05-23 at 23.18.10@2x.png
As for me, I'm going to try to forget the raw SQL queries I've seen on data.nasa.gov...

Thanks for reading !

Top comments (2)

Collapse
 
shapedgod profile image
polygon

Hello,
This doesn't work for me.

(node:12492) UnhandledPromiseRejectionWarning: Error: EISDIR: illegal operation on a directory, open 'C:\Users\Parthiv/nau/'
at Object.openSync (fs.js:476:3)
at Object.writeFileSync (fs.js:1467:35)
at C:\Users\Parthiv\AppData\Roaming\npm\node_modules\source-map-unpack\dist\index.js:47:16
at Array.forEach (<anonymous>)
at C:\Users\Parthiv\AppData\Roaming\npm\node_modules\source-map-unpack\dist\index.js:42:17
at C:\Users\Parthiv\AppData\Roaming\npm\node_modules\source-map-unpack\node_modules\source-map\lib\source-map-consumer.js:78:16
(Use `node --trace-warnings ...` to show where the warning was created)
(node:12492) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:12492) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Collapse
 
alex_rmu profile image
Alex