> ## Documentation Index
> Fetch the complete documentation index at: https://0-x.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript Obfuscation / Deobfuscation

Why do we want to obfuscate or deobfuscate code? Imagine you are in a red team engagement and are testing a web application's client-side logic, login flows, e.g. Developers often obfuscate JavaScript code before shipping it to the browser, hoping to slow down anyone reading it. As an attacker (or defender reviewing your own app), you'll frequently need to reverse that process to recover hardcoded API keys, hidden endpoints, or the real logic behind a client-side check, while on the other side, obfuscation itself is a useful technique for protecting payloads or implants from quick signature-based detection.

***

# Obfuscation

There are multiple tools online to obfuscate JavaScript code. Let's say we want to obfuscate a simple hello world program:

```javascript theme={null}
console.log('Hello from 0-x.dev')
```

After obfuscation, the code can look like any of the following, depending on the technique used:

```javascript wrap theme={null}
// Variant 1 
console['\u006C\u006F\u0067']("\u0048\u0065\u006C\u006C\u006F\u0020\u0066\u0072\u006F\u006D\u0020\u0030\u002D\u0078\u002E\u0064\u0065\u0076");
 
// Variant 2 
eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('2.1(\'3 4 0-6.5\')',7,7,'|log|console|Hello|from|dev|x'.split('|'),0,{}))
 
// Variant 3 — JSFuck: valid JavaScript written using only six characters: [ ] ( ) ! + Every character and keyword is rebuilt by coercing arrays/booleans to strings.
// Checkout the JSFuck link below for the full (very long) payload.
[][(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])
<--snip --/>
(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]])())
 
// Variant 4 — JJEncode: rebuilds the script using only non-alphanumeric characters
// and object/array coercion tricks, keyed off a small set of symbol variable names. Checkout the JJEncode link below for the full payload.
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:
<--snip --/>({}+"")\\"+$.__$+$.$$$+$.___+"."+$.$$_$+$.$$$_+"\\"+$.__$+$.$$_+$.$$_+"')"+"\"")
 
// Variant 5 — AAEncode: the same idea as JJEncode but rendered with kaomoji
// (Japanese emoticons). Checkout the AAEncode link below for the full payload.
ﾟωﾟﾉ= /｀ｍ´）ﾉ ~┻━┻   //*´∇｀*/ ['_']; o=(ﾟｰﾟ)  =_=3; c=(ﾟΘﾟ) =(ﾟｰﾟ)-(ﾟｰﾟ); (ﾟДﾟ) =(ﾟΘﾟ)= (o^_^o)/ (o^_^o);(ﾟДﾟ)={ﾟΘﾟ: '_' ,ﾟωﾟﾉ : ((ﾟωﾟﾉ==3) +'_') [ﾟΘﾟ] ,ﾟｰﾟﾉ :(ﾟωﾟﾉ+ '_') <--snip --/>
Дﾟ) ['c'] = ((ﾟДﾟ)+'_') [ (ﾟｰﾟ)+(ﾟｰﾟ)-(ﾟΘﾟ) ];(ﾟДﾟ) ['o'] = ((ﾟДﾟ)+'_') [ﾟΘﾟ];(ﾟoﾟ)=(ﾟ
```

If you open your developer tools and enter any of the code variants above, you'll get the same result: `Hello from 0-x.dev`

* [js-obfuscator.github.io](https://js-obfuscator.github.io/#obfuscator)
* [beautifytools.com/javascript-obfuscator](https://beautifytools.com/javascript-obfuscator.php)
* [obfuscator.io/legacy-playground](https://obfuscator.io/legacy-playground)
* [jsfuck.com](https://jsfuck.com/)
* [utf-8.jp/public/jjencode.html](https://utf-8.jp/public/jjencode.html)
* [utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html)

## Use cases of obfuscation

There are many reasons why developers may consider obfuscating their code. One common reason is to hide the original code and its functions to prevent it from being reused or copied without the developer's permission, making it more difficult to reverse engineer the code's original functionality. Another reason is to provide a security layer when dealing with authentication or encryption to prevent attacks on vulnerabilities that may be found within the code.

The most common usage of obfuscation, however, is for malicious actions. It is common for attackers and malicious actors to obfuscate their malicious scripts to prevent Intrusion Detection and Prevention systems from detecting their scripts.

> [!WARNING]
>
> But it must be noted that doing authentication or encryption on the client side is not recommended, as code is more prone to attacks this way.

***

# Deobfuscation

There are multiple tools and techniques to deobfuscate JavaScript code.

## Beautify the code

Obfuscated code is intentionally unformatted and very difficult to read. Start by formatting it with tools like your browser's debugger, click `{ }` in the Sources panel to pretty print it or an external tool like [Prettier](https://prettier.io/playground/) or [Beautifier](https://beautifier.io/) to make it more readable. This alone won't reverse any actual obfuscation technique, but it turns an unreadable single-line slop into something you can scroll through and reason about before going further.

## Decode with an online unpacker

You can find many good online tools to deobfuscate JavaScript code and turn it into something we can understand. One good tool is [UnPacker](https://matthewfl.com/unPacker.html), let's try to deobfuscate an obfuscated code snippet:

![Unpacker Example](https://mintcdn.com/0xdev/JViJgRrZkS34rhN5/images/techniques/javascript-obfuscation-deobfuscation/unpacker-example.png?fit=max\&auto=format\&n=JViJgRrZkS34rhN5\&q=85\&s=cf0e8141e96568d9503f45af93817b3e)

## Identify and reverse any secondary encoding

Generally, the malicious payload inside the unpacked code will itself be encoded with various techniques like Base64, HEX, Caesar cipher, ROT13, and much more. You can use a tool like [Cipher Identifier](https://www.boxentriq.com/code-breaking/cipher-identifier) to identify the encoding based on that, you can revert it. [CyberChef](https://gchq.github.io/CyberChef/) is the practical tool for actually doing the reversal once you know (or suspect) the encoding, its "Magic" operation will even attempt to auto-detect and chain multiple decodings for you. Quick manual checks are also often enough for a single layer:

```shellscript theme={null}
echo aHR0cHM6Ly8wLXguZGV2Cg== | base64 -d        // Base64 decode
echo 68747470733a2f2f302d782e6465760a | xxd -p -r  // HEX decode 
```

Malicious actors also write their own custom encoding schemes, or chain multiple encoding techniques together (e.g. Base64 → ROT13 → HEX) specifically to defeat single-pass automated decoders, if the first decode attempt produces garbage rather than readable text or valid JavaScript, feed that output back through Cipher Identifier / CyberChef rather than assuming the payload isn't encoded at all.

## Bypassing anti-debugging (`debugger` flooding)

Self-defending obfuscated code sometimes inserts a `debugger;` statement in a loop that fires continuously once DevTools is open, making it practically unusable to step through. In Chrome DevTools, right-click the line containing the `debugger` statement in the Sources panel and choose **"Never pause here"**, then continue stepping through normally.

## Tools

<table>
  <colgroup>
    <col width="164" />

    <col width="516" />
  </colgroup>

  <thead>
    <tr>
      <th>Tool</th>
      <th>Best for</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>[UnPacker](https://matthewfl.com/unPacker.html)</td>
      <td>Quick browser-based unpacker</td>
    </tr>

    <tr>
      <td>[de4js](https://lelinhtinh.github.io/de4js/)</td>
      <td>Legacy packers, JSFuck, JJEncode, and AAEncode, browser-based</td>
    </tr>

    <tr>
      <td>[synchrony](https://github.com/relative/synchrony)</td>
      <td>javascript-obfuscator / obfuscator.io output specifically (string arrays, control-flow flattening)</td>
    </tr>

    <tr>
      <td>[webcrack](https://github.com/j4k0xb/webcrack)</td>
      <td>Same target as synchrony, plus unpacking bundled webpack/browserify code</td>
    </tr>

    <tr>
      <td>[humanify](https://github.com/jehna/humanify)</td>
      <td>AI-assisted variable/function renaming - makes the result readable, not just correct</td>
    </tr>

    <tr>
      <td>[CyberChef](https://gchq.github.io/CyberChef/)</td>
      <td>Identifying and reversing secondary encoding (Base64, HEX, ROT13, Caesar, chained layers) via its "Magic" operation</td>
    </tr>
  </tbody>
</table>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.