EMAS automatically deobfuscates JavaScript SourceMaps. This topic describes what SourceMaps are and how to deobfuscate stacks.
What are SourceMaps
Why you need SourceMaps
Early web applications were less complex. Developers deployed HTML, CSS, and JavaScript files directly to the web.
Modern and complex Web/H5 applications often require various tools in the development workflow, such as:
Template languages and HTML preprocessors: Pug, Nunjucks, Markdown.
High-level programming languages: TypeScript, Dart, CoffeeScript.
These tools use a build process to convert code into HTML, JavaScript, and CSS that browsers can understand. To optimize performance, tools such as Terser compress and merge the code.
For example, you can use a build tool to transpile and compress the following TypeScript file into JavaScript:
/* A TypeScript demo: example.ts */
function greetUser() {
const username: string = 'Alice';
const message: string = `Welcome, ${username}!`;
const div = document.createElement('div');
div.innerText = message;
document.body.appendChild(div);
console.log(message);
}
greetUser();
The compressed JavaScript code may be as follows:
/* A compressed JavaScript version of the TypeScript demo: example.min.js */
!function(){const e="Alice",n=`Welcome, ${e}!`,t=document.createElement("div");t.innerText=n,document.body.appendChild(t),console.log(n)}();
Debugging compressed code is difficult. SourceMap files help by mapping the compiled code back to the original source code, making it easier to locate issues quickly.
Structure of a SourceMap file
SourceMap files contain important information that maps compiled code back to the original code to assist with debugging. The following is an example of a SourceMap:
{
"version": 3,
"file": "example.min.js",
"sources": ["src/script.ts"],
"sourcesContent": ["function greetUser() { ... }"],
"names": ["greetUser", "username", "message", "console", "log"],
"mappings": "AAAAA,SAASC,cAAc,WAAWC,..."
}
The mappings field is the most important part of a SourceMap file. It uses a VLQ base64-encoded string to map lines and positions in the compiled file to the original file. You can use a tool such as source-map-visualization to view this mapping.
The mappings section displays the decoded mapping of the code. For example, the entry 65 -> 2:2 indicates:
Generated code: The word
constis at position 65 of the compressed content.Original code: The word
constis at line 2, column 2 of the original content.
This way, developers can quickly determine the relationship between the minified code and the original code, making the debugging process smoother.
Browser developer tools apply these source maps to help you debug issues in the browser efficiently.
How browsers use SourceMaps
The main purpose of a SourceMap is to help developers view and debug the original source code rather than the compressed or transpiled code. Developer tools in modern browsers, such as Chrome DevTools and Firefox Developer Tools, support SourceMaps. The following section describes how a browser uses a SourceMap.
Loading and identifying SourceMaps
When you load a webpage that includes a SourceMap, the browser automatically detects and loads it. A special comment at the end of your compressed JavaScript or CSS file points to the SourceMap's location. For example:
/*# sourceMappingURL=example.min.css.map */
//# sourceMappingURL=example.min.js.map
This instruction tells the browser to load the corresponding .map file.
Once the browser loads the SourceMap, it parses the file to understand how to map the compressed code back to the original source code.
Debugging in developer tools
With SourceMaps, browser developer tools display the original source code for debugging instead of the compressed version. This lets you set breakpoints, inspect variables, and navigate directly to the error location in your original code without searching through compressed code. This mapping makes debugging more intuitive and efficient, simplifying the process of finding and fixing errors.
How to find SourceMap
Most major frontend task runners and bundlers can generate SourceMaps. This section uses Webpack as an example.
Webpack is a popular frontend bundler. To generate a SourceMap file, set the devtool option in your webpack.config.js configuration file:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
devtool: "source-map"
};
● The devtool option offers over 20 settings for different types of SourceMaps. Configure it as needed.● EMAS supports deobfuscation for SourceMap v3 and earlier versions.
How to upload SourceMaps
View SourceMaps
View and upload symbol tables in the H5 Application Monitoring console.
Log on to EMAS Management Console, select Application Monitoring, and click Enter to go to the Application Monitoring console.
In the navigation pane on the left, expand Configuration Management and select SourceMap Management.
Upload SourceMaps
Prepare the SourceMap files. Package the files into a zip archive. The archive size must be no more than 1 GB.
In the navigation pane on the left, select Application Monitoring. Expand Configuration Management and select SourceMap Management.
Click Upload SourceMap. Drag and drop the zip archive or browse to select it.
Enter the application version. This is the version reported during SDK integration.
Click Upload SourceMap.
Check the parsing status of the SourceMap on the current page.
View deobfuscated stacks
In the navigation pane on the left, select Application Monitoring. Expand Stability Monitoring and select JS Errors.
Select an error and click to view its details.
View the details. If the SourceMap was uploaded successfully, the error stack is deobfuscated.
If you do not see the deobfuscated stack, check the symbol table upload, or click Re-parse.