這是一張有關標題為 Restoring Frontend Source Code Using Sourcemaps: Practical Steps and Security Considerations 的圖片

Restoring Frontend Source Code Using Sourcemaps: Practical Steps and Security Considerations

Learn how to restore frontend source code from sourcemaps, with practical examples applicable to frameworks like React, Next.js, and more.

Introduction

In modern frontend development, tools like Vite, Webpack, Rollup, Parcel, and esbuild are commonly used to build and bundle frontend applications. These tools convert the written code into browser-executable JavaScript files (.js) and can also generate source map files. These files help developers debug and track issues more effectively.

Source maps are compiled to provide convenience during the development process, allowing developers to map original code to compiled code. These files usually end with .map (e.g., example.min.js.map or styles.css.map).

Through these source maps, developers can easily track and fix errors during debugging, ensuring the code works as expected before entering the production environment.

Before deploying applications to production, the code is typically further processed to enhance performance and security. These processes include minifying the code, removing comments, and applying obfuscation techniques. These steps not only reduce file size and improve load speed but also make the original code harder to reverse-engineer.

For example, a variable like let isLogin = false might be obfuscated to let a = 0 to protect the logic of the code.

In production environments, source maps are usually removed to prevent malicious individuals from reconstructing the original code. However, sometimes source maps may accidentally be compiled and uploaded with the code, which can pose potential security risks.

This article will explain how to use these source maps present on a website to reconstruct the original code. Understanding this process helps developers better protect their code and take appropriate measures to prevent potential security risks.

Analyzing Website Source Maps

First, press F12 to open the browser’s Developer Tools (DevTools) on the target webpage. Then, go to the “Sources” tab to find the original code loaded by the webpage.

If the webpage has source maps, the browser will automatically parse and restore the original code. The left image shows the obfuscated code without source maps, while the right image shows the restored original code after parsing the source maps.

No source maps in the webpage Source maps present in the webpage

In the compiled code, if source maps were chosen to be compiled, the source map information will be embedded at the bottom of the .js file. The developer tools will automatically reconstruct the original code based on this map file, as seen in the highlighted section of the right image.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
!(function () {
  var e = {},
    t = {};
  function n(r) {}

  ...

        A = document.getElementById("root");
      (0, t.H)(A).render((0, f.jsx)(x, {}));
    })();
})();
//# sourceMappingURL=main.XXXX.js.map

Analysis of Source Maps

We can directly download main.XXXX.js.map, which is in JSON format.

Here is an example of a standard source map file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
    "version": 3,
    "file": "static/js/main.XXXX.js",
    "mappings": "gUA4JA,UA1HkB,SAAHA,GAAyE,GAAG,IAEazE,EAClB,C",
    "sources": [
        "index.tsx",
        "utils/useLazyFetch.js"
        "..."
    ],
    "sourcesContent": [
      "source code of index.tsx",
      "source code of utils/useLazyFetch.js",
    ],
    "names": [
       "_ref",
       "isLazy",
       "isFetch",
       "btnSize",
       "gtmItemId",
       "useRef",
       "target",
       "...",
    ],
    "sourceRoot": ""
}

A standard source map contains the following key fields:

No.Field NameDescription
1versionIndicates the version of the source map. The version number here is usually 3, which is the most common version supported by modern browsers.
2fileIndicates the output file name corresponding to this source map file. In this example, it points to static/js/main.XXXX.js, a minified or compiled JS file.
3mappingsA complex string used to describe the mapping relationship between the minified code and the original code. This field tells the browser where each line and column of the minified code corresponds to in the original code. The string uses VLQ (Variable-Length Quantity) encoding to efficiently compress and represent this mapping information.
4sourcesAn array listing the filenames of the original code. Here, index.tsx and utils/useLazyFetch.js are two files from the original code, indicating that these files were compiled into the final main.XXXX.js.
5sourcesContentAn array containing the original content of each file in the original code. If present, it will directly show the original code content. Even if the original files are inaccessible, the developer tools can retrieve the code from the source map.
6namesAn array listing all the identifier names used in the original code (e.g., variables, function names). These names are referenced in the mappings to help the browser restore the obfuscated names back to their original names.
7sourceRootThe root directory of the original code, used to help construct the complete source file path. Usually, this is an empty string, indicating no specific root directory.

How to Restore Source Maps?

There are several tools available that can restore the original files using main.XXXX.js and main.XXXX.js.map as inputs. For example, the restore-source-tree tool. However, this tool may be outdated, as it didn’t work during my tests and could only recover one .map file at a time.

In comparison, I recommend the sourcemap tool, a powerful tool implemented in Go. You only need to provide the target website’s URL to restore the website’s frontend source code.

The process is very simple: Install Go → Clone the source project → Compile the project → Run it → Obtain the original source code.

Installing Go

Traditional Installation Method: Go to the official Go website to download and install.

Windows Installation using WinGet:

1
winget install --id GoLang.Go

Linux:

1
2
3
4
sudo apt install golang-go

# Or use Homebrew, make sure Homebrew is installed first:
brew install go

The installation process is usually straightforward. After installation, you can verify the success by checking the Go version with the following command:

1
go version

Example output:

1
2
3
4
PS C:\Users\wells> go version
go version go1.23.0 windows/amd64
# If the Go version number is displayed, the installation was successful.
# Note: If Go cannot be found after installation, check if the environment variables are set correctly.

Cloning the Sourcemap Project

Enter the following commands in your personal directory to clone and compile the project. Before proceeding, make sure you have Git installed:

1
2
3
4
5
6
7
8
# Clone the project to your local machine
git clone https://github.com/orsinium-labs/sourcemap.git
# Enter the folder
cd sourcemap
# Compile the project
go build -o sourcemap .
# On Linux, you might also need to make it executable
chmod +x ./sourcemap

Converting Website Source Maps to Source Code

In the same directory, run the following command to convert the website’s map into source code.

1
echo "https://xxxx.com/" | .\sourcemap --output=./sources

Example output:

1
2
3
PS C:\Users\wells\Desktop\sourcemap> echo "https://xxxx.com/" | .\sourcemap --output=./sources
2024-09-02T15:08:59.313+0800    INFO    sourcemap/main.go:83    running
2024-09-02T15:09:01.147+0800    INFO    sourcemap/main.go:89    finished

You can then find the original source code under ./sourcemap/sources/xxxx.com. This source code contains the folder structure, comments, package info, etc.

Restored Source Map Result

Conclusion

This article detailed how to use .js files and source maps to restore the frontend source code of a website. If source map files are exposed in a production environment, it means that users can reconstruct the original source code.

This could allow malicious individuals to discover potential vulnerabilities, APIs, test URLs, or even the author’s Gmail information (if it exists in the comments). Therefore, ensuring that source maps are not accidentally uploaded to production environments, or promptly removing these files when discovered, is crucial for protecting your source code.

Moreover, while removing source maps can effectively prevent the code from being easily restored, attention must still be paid to the security of the code logic itself. Ensuring the robustness and security of the code is key to preventing potential vulnerabilities.

References

  1. What are source maps? | web.dev
  2. orsinium-labs/sourcemap: Restore the frontend source code from source maps
Theme Stack designed by Jimmy