A more traditional web page architecture loads different pages as the user attempts to open a new web page. In this case, each HTML page is usually linked to other pages. Upon each page load, the browser fetches and displays a fresh page.
The emergence of such frameworks causes changes in the security implications it may have on the frontend. Therefore, it is necessary to understand their internal machinery while disassembling client-side code and how modern frameworks change the attack vectors.
Here’s a diagram overviewing the build process:
Transpiling enables you to write modern code which is then converted to standards and features that are supported everywhere, for e.g. ES6 -> ES5. You might use const, let to define your variables but the transpiler helps to convert it to var, internally.
A typical modern app contains hundreds of external dependencies when you look at it recursively and it isn’t practical to load each of those separately in a script tag.
With the help of this process, all of the code that makes the application work is bundled together; the business logic code as well as the boiler-plate code are bundled together.
Bundling and minification is usually done using Webpack.
Reverse engineering code
Once the code has been minified in the build process, security researchers will have to de-minify it to study the app. As most of the information such as variable names are lost during the process of minification, there isn’t a straightforward way to do this. However, there are certain tools to aid you in the process such as jsnice.org.
This tool uses machine learning to restore minified variable, function names and infer type information. It also formats the code and adds comments.
After this step, you are still left with a bundled code, but the main logic would be readable.
To debundle it into modules, we need to know how Webpack or any other bundler works.
A bundler starts with an entry point file – the root of your application logic – and traces import and require statements. It then builds a dependency graph, module A requires B which requires C and D, and so on.
If you look through the Webpack chunks after they have been passed through jsnice, you’ll find a lot of calls to “__webpack_require__(<number>).”
The only way to unbundle a bundle is to construct the abstract syntax tree (AST) manually, as there have been attempts to debundle that aren’t maintained anymore.
You could use these resources to study in depth how a bundle file works and to know the internals of Webpack. In this video, Webpack founder Tobias Koppers shows us how bundling is done manually.
How do these frameworks change attack vectors?
React does not render dynamic HTML; it sanitizes content coming from all variables, even if they do not contain dynamic content. Here XSS is all but eradicated unless the developer uses an unsafe function such as dangerouslySetInnerHTML.
In that case, even if you find data reflection you would not be able to insert HTML.
You could use certain gadgets available in Angular to bypass Content Security Policy (CSP) in certain cases.
<img src=”/” ng-on-error=”$event.srcElement.ownerDocument.defaultView.alert($event.srcElement.ownerDocument.domain)”