javascript-obfuscator 5.2.1 → 5.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  Change Log
2
2
 
3
+ v5.3.0
4
+ ---
5
+ * Add Pro API support to CLI
6
+ * Add large files upload support to Pro API
7
+
3
8
  v5.2.1
4
9
  ---
5
10
  * Fixed `transformObjectKeys` incorrectly hoisting object literal outside of loop when loop body is a single statement without braces, causing all iterations to share the same object reference. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1300
package/README.md CHANGED
@@ -15,18 +15,20 @@ Huge thanks to all supporters!
15
15
 
16
16
  ---
17
17
 
18
- ### :rocket: JavaScript Obfuscator Pro with VM Obfuscation is out!
18
+ ### :rocket: Obfuscator.io with VM Obfuscation is out!
19
19
 
20
- **JavaScript Obfuscator Pro** features **VM-based bytecode obfuscation** — the most advanced code protection available. Your JavaScript functions are transformed into custom bytecode running on an embedded virtual machine, making reverse engineering extremely difficult.
20
+ **Obfuscator.io** features **VM-based bytecode obfuscation** — the most advanced code protection available. Your JavaScript functions are transformed into custom bytecode running on an embedded virtual machine, making reverse engineering extremely difficult.
21
21
 
22
22
  [Try it at obfuscator.io](https://obfuscator.io)
23
23
 
24
+ This package provides access to Obfuscator.io Pro API via CLI and Node.js API.
25
+
24
26
  ---
25
27
 
26
28
  JavaScript Obfuscator is a powerful free obfuscator for JavaScript, containing a variety of features which provide protection for your source code.
27
29
 
28
30
  **Key features:**
29
- - VM bytecode obfuscation (via [JavaScript Obfuscator Pro](https://obfuscator.io/))
31
+ - VM bytecode obfuscation (via [Obfuscator.io](https://obfuscator.io/))
30
32
  - variables renaming
31
33
  - strings extraction and encryption
32
34
  - dead code injection
@@ -314,17 +316,17 @@ console.log(result.getObfuscatedCode());
314
316
  **Parameters:**
315
317
 
316
318
  * `sourceCode` (`string`) – source code to obfuscate
317
- * `options` (`Object`) – obfuscation options. **Must include `vmObfuscation: true`**
319
+ * `options` (`Object`) – obfuscation options. **Must include at least one Pro feature: `vmObfuscation: true` or `parseHtml: true`**
318
320
  * `apiConfig` (`Object`) – Pro API configuration:
319
321
  * `apiToken` (`string`, required) – your API token from obfuscator.io
320
322
  * `timeout` (`number`, optional) – request timeout in ms (default: `300000` - 5 minutes)
321
- * `version` (`string`, optional) – JavaScript Obfuscator Pro version to use (e.g., `'5.0.0-beta.20'`). Defaults to latest version if not specified.
323
+ * `version` (`string`, optional) – Obfuscator.io version to use (e.g., `'5.0.3'`). Defaults to latest version if not specified.
322
324
  * `onProgress` (`function`, optional) – callback for progress updates during obfuscation
323
325
 
324
326
  **Returns:** `Promise<ObfuscationResult>`
325
327
 
326
328
  **Throws:** `ApiError` if:
327
- - `vmObfuscation` is not enabled in options
329
+ - No Pro features (`vmObfuscation` or `parseHtml`) are enabled in options
328
330
  - API token is invalid or expired
329
331
  - API request fails
330
332
 
@@ -341,7 +343,7 @@ const result = await JavaScriptObfuscator.obfuscatePro(
341
343
  },
342
344
  {
343
345
  apiToken: 'your_javascript_obfuscator_pro_api_token',
344
- version: '5.0.0-beta.20' // Use specific version
346
+ version: '5.0.3' // Use specific version
345
347
  }
346
348
  );
347
349
  ```
@@ -367,6 +369,28 @@ const result = await JavaScriptObfuscator.obfuscatePro(
367
369
  );
368
370
  ```
369
371
 
372
+ ### Checking for Pro Features
373
+
374
+ Use `ProApiClient.hasProFeatures()` to check if options require the Pro API:
375
+
376
+ ```javascript
377
+ const { ProApiClient } = require('javascript-obfuscator');
378
+
379
+ const options = { vmObfuscation: true, compact: true };
380
+
381
+ if (ProApiClient.hasProFeatures(options)) {
382
+ // Use obfuscatePro() - requires API token
383
+ const result = await JavaScriptObfuscator.obfuscatePro(sourceCode, options, { apiToken });
384
+ } else {
385
+ // Use regular obfuscate() - no API token needed
386
+ const result = JavaScriptObfuscator.obfuscate(sourceCode, options);
387
+ }
388
+ ```
389
+
390
+ Pro features include:
391
+ - `vmObfuscation: true` – VM-based bytecode obfuscation
392
+ - `parseHtml: true` – HTML parsing with inline JavaScript obfuscation
393
+
370
394
  ### Error Handling
371
395
 
372
396
  ```javascript
@@ -383,6 +407,36 @@ try {
383
407
  }
384
408
  ```
385
409
 
410
+ ### CLI Usage with Pro API
411
+
412
+ You can also use Pro API features directly from the CLI by providing your API token:
413
+
414
+ ```sh
415
+ javascript-obfuscator input.js --pro-api-token YOUR_API_TOKEN --vm-obfuscation true -o output.js
416
+ ```
417
+
418
+ With a specific obfuscator version:
419
+
420
+ ```sh
421
+ javascript-obfuscator input.js --pro-api-token YOUR_API_TOKEN --pro-api-version 5.0.3 --vm-obfuscation true -o output.js
422
+ ```
423
+
424
+ **CLI Options:**
425
+ - `--pro-api-token <string>` – Your API token from [obfuscator.io](https://obfuscator.io)
426
+ - `--pro-api-version <string>` – Obfuscator.io version to use (optional, defaults to latest)
427
+
428
+ The CLI automatically detects when Pro features (`vmObfuscation` or `parseHtml`) are enabled and routes the request through the Pro API.
429
+
430
+ ### Large File Uploads
431
+
432
+ For files larger than ~4MB, the Pro API uses client-side uploads to Vercel Blob storage. To enable this feature, install the optional `@vercel/blob` package:
433
+
434
+ ```sh
435
+ npm install @vercel/blob
436
+ ```
437
+
438
+ Without this package, large file obfuscation will fail with an error message prompting you to install it.
439
+
386
440
  ---
387
441
 
388
442
  ## CLI usage
@@ -583,6 +637,37 @@ Following options are available for the JS Obfuscator:
583
637
  --target <string> [browser, browser-no-eval, node]
584
638
  --transform-object-keys <boolean>
585
639
  --unicode-escape-sequence <boolean>
640
+ --pro-api-token <string>
641
+ --pro-api-version <string>
642
+ --vm-obfuscation <boolean>
643
+ --vm-obfuscation-threshold <number>
644
+ --vm-preprocess-identifiers <boolean>
645
+ --vm-dynamic-opcodes <boolean>
646
+ --vm-target-functions '<list>' (comma separated)
647
+ --vm-exclude-functions '<list>' (comma separated)
648
+ --vm-target-functions-mode <string> [root, comment]
649
+ --vm-wrap-top-level-initializers <boolean>
650
+ --vm-opcode-shuffle <boolean>
651
+ --vm-bytecode-encoding <boolean>
652
+ --vm-bytecode-array-encoding <boolean>
653
+ --vm-bytecode-array-encoding-key <string>
654
+ --vm-bytecode-array-encoding-key-getter <string>
655
+ --vm-instruction-shuffle <boolean>
656
+ --vm-jumps-encoding <boolean>
657
+ --vm-decoy-opcodes <boolean>
658
+ --vm-dead-code-injection <boolean>
659
+ --vm-split-dispatcher <boolean>
660
+ --vm-macro-ops <boolean>
661
+ --vm-debug-protection <boolean>
662
+ --vm-runtime-opcode-derivation <boolean>
663
+ --vm-stateful-opcodes <boolean>
664
+ --vm-stack-encoding <boolean>
665
+ --vm-randomize-keys <boolean>
666
+ --vm-indirect-dispatch <boolean>
667
+ --vm-compact-dispatcher <boolean>
668
+ --vm-bytecode-format <string> [binary, json]
669
+ --parse-html <boolean>
670
+ --strict-mode <boolean>
586
671
  ```
587
672
 
588
673
  <!-- ##options-start## -->
@@ -1766,9 +1851,9 @@ The performance will be at a relatively normal level
1766
1851
 
1767
1852
  <!-- ##options-end## -->
1768
1853
 
1769
- ## JavaScript Obfuscator Pro Options
1854
+ ## Obfuscator.io Pro Options
1770
1855
 
1771
- > :warning: **The following VM obfuscation/Pro options are available only via the [JavaScript Obfuscator Pro API](https://obfuscator.io/).**
1856
+ > :warning: **The following VM obfuscation/Pro options are available only via the [Obfuscator.io Pro API](https://obfuscator.io/).**
1772
1857
  >
1773
1858
  > To use these options, you need a Pro API token from [obfuscator.io](https://obfuscator.io) and must call the `obfuscatePro()` method instead of `obfuscate()`. See the [Pro API Methods](#shield-pro-api-methods-vm-obfuscation) section for details.
1774
1859
 
@@ -1785,6 +1870,8 @@ Type: `number` Default: `1`
1785
1870
 
1786
1871
  Controls what percentage of your root-level functions get VM protection.
1787
1872
 
1873
+ > **Warning:** Values other than `1` may cause runtime bugs when VM-obfuscated and non-VM-obfuscated code share top-level variables. A value of `1` is strongly recommended. For selective function obfuscation, use `vmTargetFunctionsMode: 'comment'` with the `// javascript-obfuscator:vm` directive instead.
1874
+
1788
1875
  ### `vmPreprocessIdentifiers`
1789
1876
  Type: `boolean` Default: `true`
1790
1877
 
@@ -1915,6 +2002,56 @@ Type: `boolean` Default: `false`
1915
2002
 
1916
2003
  Encodes the entire bytecode array as a single block. The array is decoded once at startup before execution begins. Use together with `vmBytecodeEncoding` for two layers of protection.
1917
2004
 
2005
+ ### `vmBytecodeArrayEncodingKey`
2006
+ Type: `string` Default: `''`
2007
+
2008
+ Custom encryption key for bytecode array encoding. When set, this key is used instead of the default environment-derived key. The key must be provided at runtime via `vmBytecodeArrayEncodingKeyGetter`.
2009
+
2010
+ This option externalizes the encryption key - it's not embedded in the obfuscated code itself. While the key is still accessible at runtime (and thus not truly secret), this separation prevents static analysis tools from finding the key by examining the code alone.
2011
+
2012
+ **Important:** The key must be available **synchronously** when the obfuscated code loads. Use synchronous storage like cookies, localStorage, sessionStorage, global variables, or DOM elements (e.g., server-injected meta tags). Async methods like `fetch()` cannot be used directly in the key getter expression.
2013
+
2014
+ ### `vmBytecodeArrayEncodingKeyGetter`
2015
+ Type: `string` Default: `''`
2016
+
2017
+ **Synchronous** JavaScript expression that **returns** the encryption key at runtime. This expression is evaluated when the obfuscated code loads, and must return the same key that was provided in `vmBytecodeArrayEncodingKey`.
2018
+
2019
+ **The obfuscated code will only work when the key getter returns exactly the same key that was used during obfuscation.** If the keys don't match, decryption will fail and the code will produce garbage or errors. If the key getter returns `undefined`, `null`, or an empty string, the code will throw an error: "VM decryption key not available".
2020
+
2021
+ **Important:** The key should NOT be defined in the same JavaScript file/script as the obfuscated code. Doing so defeats the purpose of key externalization, as static analysis could still find the key. Store the key in a separate source: server-set cookies, localStorage populated by another script, server-injected HTML meta tags, or a global variable set by a different script that loads before the obfuscated code.
2022
+
2023
+ Examples:
2024
+ ```ts
2025
+ // From cookie
2026
+ vmBytecodeArrayEncodingKeyGetter: "document.cookie.match(/vmKey=([^;]+)/)?.[1]"
2027
+
2028
+ // From localStorage
2029
+ vmBytecodeArrayEncodingKeyGetter: "localStorage.getItem('vmKey')"
2030
+
2031
+ // From global variable
2032
+ vmBytecodeArrayEncodingKeyGetter: "window.__VM_KEY__"
2033
+
2034
+ // From meta tag (server-injected)
2035
+ vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]').content"
2036
+
2037
+ // From nested object
2038
+ vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"
2039
+ ```
2040
+
2041
+ **Usage example:**
2042
+ ```ts
2043
+ // Build time
2044
+ JavaScriptObfuscator.obfuscate(code, {
2045
+ vmObfuscation: true,
2046
+ vmBytecodeArrayEncoding: true,
2047
+ vmBytecodeArrayEncodingKey: 'mySecretKey123',
2048
+ vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
2049
+ });
2050
+
2051
+ // Runtime - key must be set before obfuscated code runs
2052
+ window.__VM_KEY__ = 'mySecretKey123';
2053
+ ```
2054
+
1918
2055
  ### `vmJumpsEncoding`
1919
2056
  Type: `boolean` Default: `false`
1920
2057
 
@@ -2001,6 +2138,17 @@ Encrypts values on the VM stack during execution. Values are encoded when pushed
2001
2138
 
2002
2139
  This option heavily affects performance.
2003
2140
 
2141
+ ### `vmInstructionShuffle`
2142
+ Type: `boolean` Default: `false`
2143
+
2144
+ Randomizes the bytecode instruction layout per function. Each function can have a different instruction array format:
2145
+ - Layout 0: `[op, arg, op, arg, ...]` (interleaved - default)
2146
+ - Layout 1: `[arg, op, arg, op, ...]` (swapped interleaved)
2147
+ - Layout 2: `[op0, op1, ..., arg0, arg1, ...]` (opcodes first, then arguments)
2148
+ - Layout 3: `[arg0, arg1, ..., op0, op1, ...]` (arguments first, then opcodes)
2149
+
2150
+ This makes pattern recognition across functions harder during analysis.
2151
+
2004
2152
  ### `vmRandomizeKeys`
2005
2153
  Type: `boolean` Default: `false`
2006
2154
 
@@ -2025,6 +2173,62 @@ Available values:
2025
2173
  * `true` - force strict mode treatment for all code, even without explicit `'use strict'` directive. Use this when your code will run in strict mode context (e.g., in ES modules, bundlers, or modern frameworks).
2026
2174
  * `false` - only explicit strict mode indicators (`'use strict'`, ES modules, class methods) are treated as strict. Parent scope inheritance still applies per JS spec.
2027
2175
 
2176
+ ### `parseHtml`
2177
+ Type: `boolean` Default: `false`
2178
+
2179
+ Enables obfuscation of JavaScript within HTML `<script>` tags.
2180
+
2181
+ When enabled, the obfuscator will:
2182
+ - Auto-detect if input is HTML (by checking for `<!DOCTYPE`, `<html>`, `<head>`, `<body>`, or `<script>` tags)
2183
+ - Extract JavaScript from `<script>` tags marked with the `data-javascript-obfuscator` attribute
2184
+ - Obfuscate each marked script individually while preserving the HTML structure
2185
+ - Inject obfuscated code back into the original positions
2186
+
2187
+ **Important:** Only scripts with the `data-javascript-obfuscator` attribute are obfuscated. Each marked script is obfuscated individually and independently. This means:
2188
+ - Code inside marked script tags **must be isolated** - it must NOT reference variables, functions, or classes defined in other marked script tags
2189
+ - Unmarked scripts can still access globals defined by marked scripts (via `var` declarations or explicit `globalThis` assignments)
2190
+ - This gives you explicit control over which scripts to protect
2191
+
2192
+ **Obfuscated (must have `data-javascript-obfuscator` attribute):**
2193
+ - `<script data-javascript-obfuscator>` - regular scripts
2194
+ - `<script type="text/javascript" data-javascript-obfuscator>` - explicitly typed scripts
2195
+ - Scripts with any additional attributes (`id`, `class`, other `data-*`, etc.)
2196
+
2197
+ **Skipped (left unchanged):**
2198
+ - Scripts without `data-javascript-obfuscator` attribute
2199
+ - `<script type="module">` - ES modules (even with the attribute)
2200
+ - `<script src="...">` - external scripts (even with the attribute)
2201
+ - Empty script tags
2202
+
2203
+ **Note:** Source maps are not generated when `parseHtml` is enabled, as they would not map correctly to the HTML output.
2204
+
2205
+ Example:
2206
+ ```ts
2207
+ // input
2208
+ const html = `<!DOCTYPE html>
2209
+ <html>
2210
+ <body>
2211
+ <!-- This script will NOT be obfuscated -->
2212
+ <script>
2213
+ var helper = 'utility';
2214
+ </script>
2215
+
2216
+ <!-- This script WILL be obfuscated -->
2217
+ <script data-javascript-obfuscator>
2218
+ var greeting = 'Hello World';
2219
+ console.log(greeting);
2220
+ </script>
2221
+ </body>
2222
+ </html>`;
2223
+
2224
+ JavaScriptObfuscator.obfuscate(html, {
2225
+ parseHtml: true,
2226
+ stringArray: true
2227
+ });
2228
+
2229
+ // output: HTML with only the marked script obfuscated
2230
+ ```
2231
+
2028
2232
  ## Frequently Asked Questions
2029
2233
 
2030
2234
  ### What javascript versions are supported?
@@ -1,3 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('../dist/index.cli').obfuscate(process.argv);
3
+ require('../dist/index.cli').obfuscate(process.argv).catch((error) => {
4
+ console.error(error.message);
5
+ process.exit(1);
6
+ });