defuscator
v1.0.1
Published
Static JavaScript deobfuscation and risk triage. Unpacks obfuscator.io string arrays, P.A.C.K.E.R., JSFuck, JJEncode and source maps, and emits JSON or SARIF - without ever executing the analyzed code.
Maintainers
Readme
defuscator
Static JavaScript deobfuscation and risk triage from the command line. The analysed code is never executed.
npx defuscator suspicious.jsNo .NET, no runtime to install: the package pulls one prebuilt binary for your platform.
What it takes apart
- obfuscator.io / javascript-obfuscator - string arrays with rotation, base64 and RC4 encodings, function and variable wrappers, every identifier style, and calls transformed into decoder lookups
- Dean Edwards P.A.C.K.E.R. -
eval(function(p,a,c,k,e,d){...}), base62 and plain - JSFuck, JJEncode, AAEncode
- Hex and unicode escapes, control-flow flattening, proxy objects, opaque predicates
- Source maps, including inline
sourceMappingURLpayloads
Usage
defuscator <file.js> [options]
cat file.js | defuscator [options]
--json Emit the full analysis as JSON.
--sarif Emit SARIF 2.1.0 for GitHub code scanning or a SOC pipeline.
--decode-only Print only the decoded, beautified output.
--sourcemap Recover original sources from an inline source map.
--obfuscate Obfuscate the input instead of analysing it.
--gate=risk Base the exit code on capability risk instead of obfuscation.
-h, --helpExit codes
0 none/low, 1 medium, 2 high (score 68 or above) - so it can gate a build directly:
defuscator bundle.js || echo "flagged"By default the exit code tracks the obfuscation score, which is what a build gate wants. An
ordinary minified library scores 0 for obfuscation but high for capability, because it calls
setTimeout and touches the DOM. Use --gate=risk to gate on capability instead - the right choice
when triaging an unknown sample rather than guarding a build.
Two scores, and why
- Obfuscation - how hard the code is trying not to be read. Measured on the original source, because deobfuscating it is what destroys the evidence.
- Capability risk - what the code would do if it ran. Measured on the decoded output, because that is where a call hidden behind a lookup table finally becomes visible.
They answer different questions and are not interchangeable. A heavily obfuscated file with a low risk score is not necessarily safe - it may simply not be fully resolved yet.
In CI
There is a GitHub Action that wraps this and uploads SARIF to code scanning:
- uses: defuscator/defuscator-action@v1
with:
paths: srcBenchmark
The engine is measured by a public, reproducible benchmark that scores decoded output by running it and comparing behaviour, including the cases it still fails: https://github.com/defuscator/deobfuscation-benchmark
Links
- Web app: https://defuscator.com/
- API docs: https://defuscator.com/Docs/Api.aspx
- Results: https://defuscator.com/Benchmark.aspx
MIT licensed.
