This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org

Javascript obfuscation

From OWASP
Jump to: navigation, search

What is JavaScript obfuscation and in app protection?

An obfuscator converts JavaScript source code into something that is virtually unreadable by humans but remains fully functional. In conjunction with obfuscation, various self-defending techniques can be injected to protect the app. For example:

  • Execution can be prevented within a debugger. This may stop easy inspection and probing.
  • Execution can be prevented if the app is tampered with in any way. This may hinder probing and theft.
  • Execution can be limited to a certain time range. This may be useful for demos.
  • Execution can be limited to running from a specified domain. This may prevent someone from easily copying and reusing it.

What are the difference between minification and obfuscation for JavaScript apps?

Both transform your JavaScript app, but their goals are entirely different. The goal of minification is to improve performance by decreasing the size of your code. A JavaScript minifier will typically remove whitespace, comments, new line characters, etc. Generally, anything that can be removed without compromising functionality is taken out. Some minifiers also change some identifier names as a way to save space. This makes the code harder to read for a casual viewer, but that is a side effect and not the main intent. The goal of obfuscation and in-app protection is to make the app harder to inspect, probe, alter or misuse.

Obfuscators typically perform standard minification techniques, but might also apply additional renaming techniques that can further reduce the size of the app. If an obfuscator stopped there, it would match or beat a minifier in size reduction. However, many of its other protection and self-defending transforms add code, so overall it may or may not reduce the size of your original app depending on your configuration options.

What is different about obfuscating Java or .NET vs. obfuscating JavaScript apps?

Unlike languages like Java or .NET which compile to some type of intermediate language before being distributed as binary executables, JavaScript apps are generally delivered as source code for execution. That makes it inherently more difficult to protect them from copying, inspection, theft and tampering. And hackers can easily step through the executing code via a debugger built into their browser. Also, since they have the source, they can easily use tools to statically analyze the code for vulnerabilities.

Java or .NET -> Compiler -> Executable -> Obfuscator & Protector -> Protected Executable

JavaScript Source Code -> Obfuscator & Protector -> Protected Source Code

What criteria should I consider when deciding to obfuscate and protect a JavaScript app?

  • Does it contain code you don't want competitors to copy or steal?
  • Would an attacker want to bypass some of your checks or actively look for vulnerabilities?
  • Is there a risk that the code might be modified to serve malware, enable phishing, etc.?

If the answer is “yes” to any of these questions, then you might consider obfuscating and protecting your JavaScript code. It will make it more difficult for a hacker to do these things. However, obfuscating and protecting your JavaScript will NOT make these things impossible, only much harder. The only way to completely protect JavaScript code is to not run in it in an untrusted environment where potential attackers can access it. But with today’s architectures, it is usually not possible to implement this strategy, because your JavaScript needs to run in web browsers, on mobile devices, on desktops, or even on servers hosted on networks that you don’t control. Obfuscation and other in-app protection techniques provide another layer of security in these situations. In addition, attackers can use many different paths through your application to do harm to your business or organization.

For a more comprehensive look at these attack vectors see:

What are some techniques used by a JavaScript Obfuscator and Protection Tool?

  • Renaming changes the name of identifiers making them much harder for a human to read. The new names can follow different schemes like "a", "b", "c", or unprintable characters. Names may be used multiple times in a scope by using function overloading. Renaming is a basic technique used by almost every obfuscator.
  • Control Flow Obfuscationcreates conditional, branching, and iterative constructs that produce valid executable logic, but are much harder for humans to understand.
  • String Encryption encodes string literals in the source code, and adds logic to decode them when needed. This removes clues that attackers and tools use to understand the code when performing static analysis.
  • Integer and Boolean Transformations transforms integer and Boolean literals into equivalent expressions that are harder to statically analyze and understand.
  • Dummy Code Insertion inserts code that does not affect the program’s logic, but makes the code much harder to analyze.
  • Debugger Removal removes key information from JavaScript making it harder for hackers to inspect.
  • PropertyIndirection changes direct property access to indirect property access making it harder to follow code execution. This also allows property names to be encoded.
  • DomainLock binds the code to a domain or subdomain. If the JavaScript is downloaded to the browser from a non-matching domain, it will break.
  • DateLock allows the code to only run in a certain date range. If the current date is not in that range the code will fail to execute properly.
  • Self-Defending Functions wraps code to observe if a function’s body has been altered in any way. If it has, then the code will fail to execute properly.
  • Debugger Detection prevents the code from running when a debugger is active. If the code detects that it is running inside a debugger, it will stop running.

Further Reading