JavaScript is commonly obfuscated in web apps (client-side logic hiding), malware droppers, skimmers, and trackers. Goal: beautify, unpack, simplify, and recover meaningful logic.
- View source (
Ctrl+U) or DevTools Sources tab. - Beautify first (unminify).
- Run automated deobfuscators.
- Manual: CyberChef recipes, browser console eval tricks, or local Node.
- For heavy obfuscation (obfuscator.io, VM-based): use specialized unpackers + LLM assistance if available.
| Command / Tool | Description |
|---|---|
curl -s http://target/app.js | head -c 500 |
Fetch suspicious JS |
js-beautify -o clean.js obfuscated.js |
CLI beautify (npm i -g js-beautify) |
cat obfuscated.js | xxd -p | tr -d '\n' |
Quick hex view |
| Browser: F12 → Sources → {} (pretty print) | Built-in beautify |
| CyberChef "From Base64", "JavaScript Beautify", "Generic Code Beautify" | Swiss-army knife for layers |
- deobfuscate.io — Excellent general-purpose, detects common patterns (string array, etc.)
- de4js — Auto decode + unpacker
- UnPacker — Good for packed/eval
- JSNice — ML-renaming variables
- Prettier or Beautifier.io
- CyberChef (https://gchq.github.io/CyberChef/)
Local / Advanced:
- REstringer (https://github.com/HumanSecurity/restringer)
- Webcrack or deobfuscator (npm)
- Node +
vmto step through
- String array + encoding (base64, rot13, hex, unicode escapes): Decode array entries manually or with script.
eval/Function/setTimeout(..., "code"): Replace withconsole.logor use debugger breakpoints.- Control flow flattening / opaque predicates: Harder; use symbolic execution or tools like Synchrony.
- Minification only: Just beautify.
- Polyglot / mixed: Extract the JS portion first.
Example simple decode snippet (browser console or Node):
// After beautify
const _0xabc = ['hello', 'world'];
function _0xdef(a) { return _0xabc[a]; }
console.log(_0xdef(0) + ' ' + _0xdef(1));Browser console quick wins:
// Pretty print already loaded script
copy(document.scripts[0].innerHTML) // then paste into beautifier
// Decode common patterns
atob('base64string')
String.fromCharCode(72,101,108,108,111)Node.js local deobfuscation:
# Install
npm install -g js-beautify deobfuscate
# Run
js-beautify -o clean.js obfuscated.js
deobfuscate -i heavy.js -o clean.jsCyberChef recipe example (copy-paste into CyberChef):
- From Base64 → To Hex → Generic Code Beautify → JavaScript Beautify
Deobfuscate.io usage:
- Paste minified/obfuscated code
- Click "Deobfuscate"
- Repeat if multiple layers
Handling packed / eval-heavy:
- Search for
eval(and replace temporarily withconsole.log(orwindow.DEBUG= - Use debugger; statement + step through in DevTools Sources
- For obfuscator.io: often need multiple passes through de4js + manual array resolution
Extracting from HTML page:
curl -s https://target/app.js | grep -oP 'eval\(.+?\)' | head -5- LLM-powered tools (e.g. CASCADE research at Google) and local LLMs can help with renaming + logic recovery.
- For bug bounties / web: focus on interesting client-side logic (auth, payments, tracking pixels).
- Malware JS: Combine with static analysis (VirusTotal, any.run) + dynamic (browser sandbox).
- Always test recovered payloads in isolated env.
Ctrl+Shift+I(or F12) → Console for quickJSON.stringifyoratob().- For very large files use VS Code + Prettier extension.
References: HackTricks JS section, PortSwigger, deobfuscate.io blog, REstringer repo.