javascript-obfuscator 5.6.0 → 5.8.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 +9 -0
- package/README.md +120 -118
- package/dist/index.browser.js +4 -4
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cli.js +1 -1
- package/dist/index.cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/typings/src/cli/JavaScriptObfuscatorCLI.d.ts +2 -0
- package/typings/src/interfaces/options/IOptions.d.ts +1 -0
- package/typings/src/interfaces/pro-api/IProApiClient.d.ts +8 -4
- package/typings/src/options/Options.d.ts +3 -1
- package/typings/src/pro-api/ProApiClient.d.ts +8 -1
- package/typings/src/pro-api/enums/ProOptionsPreset.d.ts +12 -0
- package/typings/src/types/options/TInputCLIOptions.d.ts +4 -1
- package/typings/src/types/options/TInputOptions.d.ts +4 -1
- package/typings/src/types/options/TInputOptionsPreset.d.ts +2 -0
- package/typings/src/utils/AdvertisementUtils.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
Change Log
|
|
2
2
|
|
|
3
|
+
v5.8.0
|
|
4
|
+
---
|
|
5
|
+
* Pro API: added support for custom presets. `optionsPreset` accepts the alias of a custom preset saved in the obfuscator.io dashboard; `obfuscatePro()` and the CLI (`--pro-api-token`) fetch it and merge its options
|
|
6
|
+
* CLI: `--options-preset` with a VM preset name (e.g. `vm-default`) no longer fails locally when `--pro-api-token` is set; the name is passed to the Pro API
|
|
7
|
+
|
|
8
|
+
v5.7.0
|
|
9
|
+
---
|
|
10
|
+
* **New option:** `advertisement` allows to control the display of the JavaScript Obfuscator Pro advertisement message in the console. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1448
|
|
11
|
+
|
|
3
12
|
v5.6.0
|
|
4
13
|
---
|
|
5
14
|
* Pro API: `obfuscatePro` now fall back to the basic local obfuscation API when no Pro feature (`vmObfuscation` or `parseHtml`) is enabled, instead of throwing an `ApiError`
|
package/README.md
CHANGED
|
@@ -91,7 +91,6 @@ The example of obfuscated code: [github.com](https://github.com/javascript-obfus
|
|
|
91
91
|
[](https://coveralls.io/github/javascript-obfuscator/javascript-obfuscator)
|
|
92
92
|
[](#backers)
|
|
93
93
|
[](#sponsors)
|
|
94
|
-
[](https://xscode.com/sanex3339/javascript-obfuscator)
|
|
95
94
|
|
|
96
95
|
#### *NOTE! the README on the master branch might not match that of the latest stable release!*
|
|
97
96
|
|
|
@@ -421,6 +420,29 @@ if (ProApiClient.hasProFeatures(options)) {
|
|
|
421
420
|
Pro features include:
|
|
422
421
|
- `vmObfuscation: true` – VM-based bytecode obfuscation
|
|
423
422
|
- `parseHtml: true` – HTML parsing with inline JavaScript obfuscation
|
|
423
|
+
- `optionsPreset` set to a VM preset (`vm-default`, ...) or to a [custom preset](#custom-presets) alias – only the Pro API can resolve these
|
|
424
|
+
|
|
425
|
+
### Custom Presets :new:
|
|
426
|
+
|
|
427
|
+
Save a configuration in the [obfuscator.io](https://obfuscator.io) dashboard as a custom preset and give it an **API alias** in the save dialog. Set `optionsPreset` to that alias and `obfuscatePro()` fetches the preset's options before obfuscating, so the configuration lives in the dashboard and changes there apply to the next build:
|
|
428
|
+
|
|
429
|
+
```javascript
|
|
430
|
+
const result = await JavaScriptObfuscator.obfuscatePro(
|
|
431
|
+
sourceCode,
|
|
432
|
+
{ optionsPreset: 'production' },
|
|
433
|
+
{ apiToken: 'YOUR_API_TOKEN' }
|
|
434
|
+
);
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
The preset's options are the base and any other option you pass overrides them, the same way built-in presets are merged. A custom preset with no Pro feature enabled is obfuscated locally with its options. A team service key resolves the team owner's presets; a member's personal key resolves their own presets plus the ones shared with the team.
|
|
438
|
+
|
|
439
|
+
An alias that does not exist for your account throws an `ApiError` with `statusCode` 404. Without an API token (`obfuscate()`), only the built-in presets are available.
|
|
440
|
+
|
|
441
|
+
The same works from the CLI:
|
|
442
|
+
|
|
443
|
+
```sh
|
|
444
|
+
javascript-obfuscator input.js --pro-api-token YOUR_API_TOKEN --options-preset production -o output.js
|
|
445
|
+
```
|
|
424
446
|
|
|
425
447
|
### Error Handling
|
|
426
448
|
|
|
@@ -456,7 +478,7 @@ javascript-obfuscator input.js --pro-api-token YOUR_API_TOKEN --pro-api-version
|
|
|
456
478
|
- `--pro-api-token <string>` – Your API token from [obfuscator.io](https://obfuscator.io)
|
|
457
479
|
- `--pro-api-version <string>` – Obfuscator.io version to use (optional, defaults to latest)
|
|
458
480
|
|
|
459
|
-
The CLI automatically detects when Pro features (`vmObfuscation` or `
|
|
481
|
+
The CLI automatically detects when Pro features (`vmObfuscation`, `parseHtml`, or an `optionsPreset` naming a VM preset or a [custom preset](#custom-presets)) are enabled and routes the request through the Pro API.
|
|
460
482
|
|
|
461
483
|
### Large File Uploads
|
|
462
484
|
|
|
@@ -555,6 +577,7 @@ Following options are available for the JS Obfuscator:
|
|
|
555
577
|
|
|
556
578
|
```javascript
|
|
557
579
|
{
|
|
580
|
+
advertisement: true,
|
|
558
581
|
compact: true,
|
|
559
582
|
controlFlowFlattening: false,
|
|
560
583
|
controlFlowFlatteningThreshold: 0.75,
|
|
@@ -618,6 +641,7 @@ Following options are available for the JS Obfuscator:
|
|
|
618
641
|
|
|
619
642
|
-o, --output
|
|
620
643
|
|
|
644
|
+
--advertisement <boolean>
|
|
621
645
|
--compact <boolean>
|
|
622
646
|
--config <string>
|
|
623
647
|
--control-flow-flattening <boolean>
|
|
@@ -715,6 +739,13 @@ Following options are available for the JS Obfuscator:
|
|
|
715
739
|
|
|
716
740
|
<!-- ##options-start## -->
|
|
717
741
|
|
|
742
|
+
### `advertisement`
|
|
743
|
+
Type: `boolean` Default: `true`
|
|
744
|
+
|
|
745
|
+
Allows to control the display of the JavaScript Obfuscator Pro advertisement message in the console.
|
|
746
|
+
|
|
747
|
+
The message is only shown when using the Node.js CLI in an interactive (TTY) terminal, is never shown in CI environments or in the browser, and is limited to a few displays. Set this option to `false` to disable the advertisement message completely.
|
|
748
|
+
|
|
718
749
|
### `compact`
|
|
719
750
|
Type: `boolean` Default: `true`
|
|
720
751
|
|
|
@@ -1133,6 +1164,10 @@ Available values:
|
|
|
1133
1164
|
* `medium-obfuscation`;
|
|
1134
1165
|
* `high-obfuscation`.
|
|
1135
1166
|
|
|
1167
|
+
With `obfuscatePro()` or `--pro-api-token` the following are also accepted and resolved by the Pro API:
|
|
1168
|
+
* the VM presets: `vm-low-obfuscation`, `vm-default`, `vm-medium-obfuscation`, `vm-high-obfuscation`, `vm-ultra-high-obfuscation`, `vm-anti-llm`;
|
|
1169
|
+
* the alias of a [custom preset](#custom-presets) saved in the [obfuscator.io](https://obfuscator.io) dashboard.
|
|
1170
|
+
|
|
1136
1171
|
All addition options will be merged with selected options preset.
|
|
1137
1172
|
|
|
1138
1173
|
### `renameGlobals`
|
|
@@ -1916,8 +1951,8 @@ Specify exactly which root-level functions should get VM protection by name.
|
|
|
1916
1951
|
**Example:**
|
|
1917
1952
|
```javascript
|
|
1918
1953
|
{
|
|
1919
|
-
|
|
1920
|
-
|
|
1954
|
+
vmObfuscation: true,
|
|
1955
|
+
vmTargetFunctions: ['someFunctionName']
|
|
1921
1956
|
}
|
|
1922
1957
|
```
|
|
1923
1958
|
|
|
@@ -1931,8 +1966,8 @@ Specify root-level functions that should never get VM protection. Takes preceden
|
|
|
1931
1966
|
**Example:**
|
|
1932
1967
|
```javascript
|
|
1933
1968
|
{
|
|
1934
|
-
|
|
1935
|
-
|
|
1969
|
+
vmObfuscation: true,
|
|
1970
|
+
vmExcludeFunctions: ['someFunctionName']
|
|
1936
1971
|
}
|
|
1937
1972
|
```
|
|
1938
1973
|
|
|
@@ -1952,28 +1987,28 @@ Controls how functions/methods are selected for VM obfuscation.
|
|
|
1952
1987
|
```javascript
|
|
1953
1988
|
// Source code
|
|
1954
1989
|
function regularFunction() {
|
|
1955
|
-
|
|
1990
|
+
return 'not virtualized';
|
|
1956
1991
|
}
|
|
1957
1992
|
|
|
1958
1993
|
/* javascript-obfuscator:vm */
|
|
1959
1994
|
function sensitiveFunction() {
|
|
1960
|
-
|
|
1995
|
+
return 'this will be VM-protected';
|
|
1961
1996
|
}
|
|
1962
1997
|
|
|
1963
1998
|
function outer() {
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1999
|
+
/* javascript-obfuscator:vm */
|
|
2000
|
+
function nestedSensitive() {
|
|
2001
|
+
return 'nested but still VM-protected';
|
|
2002
|
+
}
|
|
2003
|
+
return nestedSensitive();
|
|
1969
2004
|
}
|
|
1970
2005
|
```
|
|
1971
2006
|
|
|
1972
2007
|
```javascript
|
|
1973
2008
|
// Obfuscator options
|
|
1974
2009
|
{
|
|
1975
|
-
|
|
1976
|
-
|
|
2010
|
+
vmObfuscation: true,
|
|
2011
|
+
vmTargetFunctionsMode: 'comment'
|
|
1977
2012
|
}
|
|
1978
2013
|
```
|
|
1979
2014
|
|
|
@@ -2034,6 +2069,8 @@ const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden
|
|
|
2034
2069
|
|
|
2035
2070
|
**Note:** This option only works when `vmTargetFunctionsMode` is `'root'` (the default).
|
|
2036
2071
|
|
|
2072
|
+
**Warnings:** Whenever a top-level initializer ends up in plain JavaScript under VM obfuscation, a `VMTopLevelInitializerNotVirtualized` warning listing the affected variable names is reported. That covers: this option being disabled, initializers this option had to skip (each with the reason — e.g. the initializer references a sibling declarator or contains top-level await), and `vmAsyncExecutor` mode where the synchronous wrappers can't be virtualized at all.
|
|
2073
|
+
|
|
2037
2074
|
### `vmDynamicOpcodes`
|
|
2038
2075
|
Type: `boolean` Default: `false`
|
|
2039
2076
|
|
|
@@ -2048,7 +2085,7 @@ As the result - smaller output and each build looks different.
|
|
|
2048
2085
|
### `vmBytecodeEncoding`
|
|
2049
2086
|
Type: `boolean` Default: `false`
|
|
2050
2087
|
|
|
2051
|
-
Encodes each bytecode instruction
|
|
2088
|
+
Encodes each bytecode instruction (decoded one at a time during execution) and masks the string constants stored in the bytecode pool, so plaintext strings do not sit in the compiled bytecode.
|
|
2052
2089
|
|
|
2053
2090
|
### `vmBytecodeArrayEncoding`
|
|
2054
2091
|
Type: `boolean` Default: `false`
|
|
@@ -2067,11 +2104,15 @@ This option externalizes the encryption key - it's not embedded in the obfuscate
|
|
|
2067
2104
|
### `vmBytecodeArrayEncodingKeyGetter`
|
|
2068
2105
|
Type: `string` Default: `''`
|
|
2069
2106
|
|
|
2070
|
-
**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`.
|
|
2107
|
+
**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`. To resolve the key **asynchronously** (a `Promise`), enable [`vmAsyncExecutor`](#vmasyncexecutor).
|
|
2108
|
+
|
|
2109
|
+
> **Note:** a Promise-returning getter requires `vmAsyncExecutor`. This can't be checked at build time, so a Promise getter with `vmAsyncExecutor` **off** fails at runtime — the decoder receives the Promise instead of the key.
|
|
2110
|
+
|
|
2111
|
+
**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 — or the getter returns `undefined`, `null`, or an empty string — decryption produces a wrong keystream and the code fails at runtime with garbage output or an ordinary runtime error. There is deliberately no distinct, key-specific error message, so a failed key is indistinguishable from any other runtime fault.
|
|
2071
2112
|
|
|
2072
|
-
**
|
|
2113
|
+
**Important:** Keep the key out of the same file/script as the obfuscated code — inlining it there lets even a purely **static** scan of the bundle recover it. Store it in a separate source instead: server-set cookies, `localStorage` populated by another script, a server-injected HTML meta tag, a global set by a different script, or (with [`vmAsyncExecutor`](#vmasyncexecutor)) fetched from your backend at runtime.
|
|
2073
2114
|
|
|
2074
|
-
|
|
2115
|
+
When the key is fetched from your backend (via [`vmAsyncExecutor`](#vmasyncexecutor)), add session- or origin-based checks on that endpoint: return the correct key to real users (valid session, expected `Origin`/`Referer`) and a garbage key to suspicious requests (e.g. a `localhost`/unexpected origin, no session). Real users run normally; a copy running outside your environment gets a key that decrypts to nothing. The exact logic depends on your site.
|
|
2075
2116
|
|
|
2076
2117
|
Examples:
|
|
2077
2118
|
```ts
|
|
@@ -2089,16 +2130,19 @@ vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]
|
|
|
2089
2130
|
|
|
2090
2131
|
// From nested object
|
|
2091
2132
|
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"
|
|
2133
|
+
|
|
2134
|
+
// From backend, async (requires vmAsyncExecutor)
|
|
2135
|
+
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
|
|
2092
2136
|
```
|
|
2093
2137
|
|
|
2094
2138
|
**Usage example:**
|
|
2095
2139
|
```ts
|
|
2096
2140
|
// Build time
|
|
2097
2141
|
JavaScriptObfuscator.obfuscate(code, {
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2142
|
+
vmObfuscation: true,
|
|
2143
|
+
vmBytecodeArrayEncoding: true,
|
|
2144
|
+
vmBytecodeArrayEncodingKey: 'mySecretKey123',
|
|
2145
|
+
vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
|
|
2102
2146
|
});
|
|
2103
2147
|
|
|
2104
2148
|
// Runtime - key must be set before obfuscated code runs
|
|
@@ -2148,25 +2192,36 @@ Type: `boolean` Default: `false`
|
|
|
2148
2192
|
|
|
2149
2193
|
Encodes jump targets in the bytecode. Jump offsets are calculated at runtime, hiding the control flow structure (`if`/`else`, loops, etc.) from static analysis.
|
|
2150
2194
|
|
|
2151
|
-
### `
|
|
2195
|
+
### `vmMacroOps`
|
|
2152
2196
|
Type: `boolean` Default: `false`
|
|
2153
2197
|
|
|
2154
|
-
|
|
2198
|
+
Combines common instruction sequences into single "macro" opcodes. For example, `LOAD_ARG + PUSH_CONST + SUB` can become `MACRO_SUB_ARG_CONST`, reducing interpreter dispatches. This works with both the default stack VM and `vmRegisterBased: true`; enable `vmMacroOps: true` explicitly in either mode.
|
|
2155
2199
|
|
|
2156
|
-
### `
|
|
2157
|
-
Type: `boolean` Default: `false`
|
|
2200
|
+
### `vmDebugProtection`
|
|
2201
|
+
Type: `boolean | object` Default: `false`
|
|
2158
2202
|
|
|
2159
|
-
|
|
2203
|
+
Adds multi-layered anti-debugging, anti-analysis, and anti-LLM defenses to the VM runtime. Works best with `browser`/`browser-no-eval` targets.
|
|
2160
2204
|
|
|
2161
|
-
|
|
2162
|
-
Type: `boolean` Default: `false`
|
|
2205
|
+
Pass `true` to enable it, or `false` to disable it. Pass an object to enable it while turning off a specific defense:
|
|
2163
2206
|
|
|
2164
|
-
|
|
2207
|
+
```js
|
|
2208
|
+
{
|
|
2209
|
+
vmDebugProtection: {
|
|
2210
|
+
// most defenses are always on; but CDP/devtools detection is disabled
|
|
2211
|
+
inspectorDetection: false
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
```
|
|
2165
2215
|
|
|
2166
|
-
|
|
2167
|
-
|
|
2216
|
+
> :warning: **The object is not a menu of defenses to switch on.** When debug protection is enabled, the great majority of its defenses are **always active and cannot be turned off**. The sub-options below expose only the small number of defenses that some consumers may deliberately need to relax (for example, because a false positive would break a legitimate workflow) — every other defense stays on regardless.
|
|
2217
|
+
|
|
2218
|
+
| Sub-option | Type | Default | Description |
|
|
2219
|
+
| --- | --- | --- | --- |
|
|
2220
|
+
| `inspectorDetection` | `boolean` | `true` | Detect and react to an attached CDP (Chrome DevTools Protocol) inspector — both the CDP `Runtime` domain being enabled (`Runtime.enable`) and an active debugger (the CDP `Debugger` domain, e.g. breakpoints or the developer-tools Sources panel). **Opening the browser's developer tools enables those domains, so an open inspector is detected and reacted to.** Keeping it enabled is recommended; set it to `false` only if your users legitimately open developer tools. |
|
|
2221
|
+
|
|
2222
|
+
> :bulb: The object form is available through the API
|
|
2168
2223
|
|
|
2169
|
-
|
|
2224
|
+
> :warning: **Automation frameworks.** With `inspectorDetection` on (the default), driving the protected page with a CDP-based tool (Puppeteer, Playwright, Selenium/ChromeDriver) is detected as an attached inspector. If you run automated tests against protected code, build those with `vmDebugProtection: { inspectorDetection: false }`.
|
|
2170
2225
|
|
|
2171
2226
|
### `vmSelfDefending`
|
|
2172
2227
|
Type: `boolean` Default: `false`
|
|
@@ -2175,12 +2230,21 @@ Adds multi-layered tamper detection, anti-hooking, and anti-reverse-engineering
|
|
|
2175
2230
|
|
|
2176
2231
|
> :warning: This option force-enables [`vmBytecodeArrayEncoding`](#vmbytecodeArrayEncoding).
|
|
2177
2232
|
|
|
2233
|
+
> :warning: **Sensitive environment detection.** This option binds the obfuscated code to its target runtime environment and uses advanced browser fingerprinting to detect automation tools. Code protected with this option **will intentionally break** when run in:
|
|
2234
|
+
> - Headless browsers (headless Chrome/Chromium, PhantomJS)
|
|
2235
|
+
> - Browser automation tools (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
|
|
2236
|
+
> - Node.js (when `target` is set to `browser`)
|
|
2237
|
+
> - jsdom or similar server-side DOM emulations
|
|
2238
|
+
> - Environments where native browser builtins have been hooked or replaced
|
|
2239
|
+
>
|
|
2240
|
+
> The code **will work correctly** in regular browsers (Chrome, Firefox, Safari, Edge), including when loaded inside iframes, browser extensions (content scripts), and Web Workers. If you need to run automated tests against protected code, disable `vmSelfDefending` for test builds — this option is designed to prevent automated analysis and **cannot be safely used with any automation framework**.
|
|
2241
|
+
|
|
2178
2242
|
Strongly recommended to use together with [`vmDebugProtection`](#vmDebugProtection), [`vmBytecodeArrayEncodingKey`](#vmbytecodeArrayEncodingKey), and [`vmBytecodeArrayEncodingKeyGetter`](#vmbytecodeArrayEncodingKeyGetter).
|
|
2179
2243
|
|
|
2180
2244
|
### `vmDefenseHook`
|
|
2181
|
-
Type: `{ name: string, aliases?: object }` Default: `
|
|
2245
|
+
Type: `{ name: string, aliases?: object } | null` Default: `null`
|
|
2182
2246
|
|
|
2183
|
-
`vmDefenseHook`
|
|
2247
|
+
`vmDefenseHook` is `null` (disabled) or an object with two keys: **`name`** (required) and **`aliases`** (optional).
|
|
2184
2248
|
|
|
2185
2249
|
`name` is a **global function your host page defines** that a VM defense (`vmDebugProtection` / `vmSelfDefending`) calls with a signal object when it detects a hostile signal — a debugger or inspector, a headless / automation browser, an AI-coding-agent process, a disallowed domain, and so on. Use it to report the event to your backend (e.g. `navigator.sendBeacon`). The hook is a **pure telemetry sink**: its return value is ignored, and a missing or throwing hook is a silent no-op that can never disable a defense. To change what a defense *does* on detection, use [`vmDefenseReaction`](#vmdefensereaction).
|
|
2186
2250
|
|
|
@@ -2240,8 +2304,6 @@ vmDefenseHook: {
|
|
|
2240
2304
|
|
|
2241
2305
|
This is fingerprint avoidance, not secrecy — the mapping can still be inferred by repeated testing — so its only benefit is not exposing stable, self-explanatory names. Unset entries keep their default names.
|
|
2242
2306
|
|
|
2243
|
-
> A bare string (`vmDefenseHook: '__vmDetection'`) is accepted as shorthand for `{ name: '__vmDetection' }` but is **deprecated** — prefer the object form.
|
|
2244
|
-
|
|
2245
2307
|
### `vmDefenseReaction`
|
|
2246
2308
|
Type: `object` Default: `{ automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }`
|
|
2247
2309
|
|
|
@@ -2276,17 +2338,33 @@ vmDefenseReaction: { automation: 'none', domain: 'break' } // tolerate automat
|
|
|
2276
2338
|
### `browserEnvironment`
|
|
2277
2339
|
Type: `object` Default: `{}`
|
|
2278
2340
|
|
|
2279
|
-
Declares facts about the environment your production build
|
|
2341
|
+
Declares facts about the environment your production build runs in, so the protected code can bind to, react to, or tolerate them. Available only for `browser` / `browser-no-eval` / `service-worker` targets — it is rejected for `node`, `userscript`, and `bytenode`. Each field takes effect together with a specific protection, noted below.
|
|
2280
2342
|
|
|
2281
|
-
|
|
2343
|
+
Fields:
|
|
2282
2344
|
|
|
2283
|
-
- **`transport`** — the scheme your production serves the bundle over: `'http'` or `'https'`. With `'https'`, the build ties its integrity to being served over HTTPS, so a copy an analyst lifts and serves over plain HTTP (a common local reverse-engineering setup) will not run correctly. `'http'` or an unset field adds no binding.
|
|
2345
|
+
- **`transport`** — the scheme your production serves the bundle over: `'http'` or `'https'`. With `'https'`, the build ties its integrity to being served over HTTPS, so a copy an analyst lifts and serves over plain HTTP (a common local reverse-engineering setup) will not run correctly. `'http'` or an unset field adds no binding. Takes effect with [`vmSelfDefending`](#vmselfdefending).
|
|
2284
2346
|
|
|
2285
2347
|
```js
|
|
2286
2348
|
browserEnvironment: { transport: 'https' }
|
|
2287
2349
|
```
|
|
2288
2350
|
|
|
2289
|
-
|
|
2351
|
+
- **`hosting`** — where your production bundle is served from: `'remote'` or `'local'`. With `'remote'`, the build ties its integrity to being served from a remote host, so a copy an analyst lifts and runs in their own local setup is treated as a runtime-environment mismatch and the automation defenses react (see [`vmDebugProtection`](#vmdebugprotection) and [`vmDefenseReaction`](#vmdefensereaction)). `'local'` or an unset field adds no binding. Takes effect with `vmDebugProtection`, on `browser` / `browser-no-eval` only.
|
|
2352
|
+
|
|
2353
|
+
```js
|
|
2354
|
+
browserEnvironment: { transport: 'https', hosting: 'remote' }
|
|
2355
|
+
```
|
|
2356
|
+
|
|
2357
|
+
- **`hookedBuiltins`** — set to `true` to declare that the runtime your production build runs in legitimately replaces native builtins with JavaScript wrappers: the app's own anti-tamper, the host page, or other browser extensions sharing the same realm. [`vmSelfDefending`](#vmselfdefending) normally treats a replaced native builtin as tampering and stops the build from running; with this set, it tolerates such an environment and the code runs. `false` or an unset field keeps the strict behavior. Takes effect with [`vmSelfDefending`](#vmselfdefending).
|
|
2358
|
+
|
|
2359
|
+
```js
|
|
2360
|
+
browserEnvironment: { hookedBuiltins: true }
|
|
2361
|
+
```
|
|
2362
|
+
|
|
2363
|
+
This option relaxes nativity checks only; clean-realm validation and required builtin behavior remain enforced.
|
|
2364
|
+
|
|
2365
|
+
> :warning: `hookedBuiltins` deliberately relaxes tamper detection: once it is set, an analyst who wraps those same builtins to inspect your code is no longer stopped either. The VM virtualization, anti-debugging, and integrity protections are unaffected. Enable it only when your production runtime is known to hook builtins and that weaker guarantee is acceptable.
|
|
2366
|
+
|
|
2367
|
+
> :warning: The `transport` and `hosting` fields bind the protected build to the environment you declare. The same build loaded in any environment that does not match — including transiently, before it reaches its final one — will not run correctly, by design. Declare a field only when every context that loads your production build matches it, and keep these declarations off the builds you use for local development, testing, and CI.
|
|
2290
2368
|
|
|
2291
2369
|
### `vmStatefulOpcodes`
|
|
2292
2370
|
Type: `boolean` Default: `false`
|
|
@@ -2345,7 +2423,6 @@ When enabled, the string array will **only** extract strings from bytecode data
|
|
|
2345
2423
|
- When `vmBytecodeArrayEncoding: true` — top-level base64 encoded bytecode strings are extracted
|
|
2346
2424
|
- `stringArrayThreshold` still controls what percentage of those bytecode strings are extracted
|
|
2347
2425
|
|
|
2348
|
-
|
|
2349
2426
|
### `vmDomainLock`
|
|
2350
2427
|
Type: `string[]` Default: `[]`
|
|
2351
2428
|
|
|
@@ -2365,81 +2442,6 @@ Type: `string` Default: `about:blank`
|
|
|
2365
2442
|
|
|
2366
2443
|
Allows the browser to be redirected to a passed URL if the source code isn't run on the domains specified by [`vmDomainLock`](#vmdomainlock).
|
|
2367
2444
|
|
|
2368
|
-
### `strictMode`
|
|
2369
|
-
Type: `boolean | null` Default: `null`
|
|
2370
|
-
|
|
2371
|
-
Allows to specify how the obfuscator should treat code regarding JavaScript strict mode.
|
|
2372
|
-
|
|
2373
|
-
Available values:
|
|
2374
|
-
* `null` (default) - auto-detect strict mode from the code. If the code has explicit `'use strict'` directive, ES module syntax, or class methods, it's treated as strict mode. Otherwise, sloppy mode is assumed.
|
|
2375
|
-
* `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).
|
|
2376
|
-
* `false` - only explicit strict mode indicators (`'use strict'`, ES modules, class methods) are treated as strict. Parent scope inheritance still applies per JS spec.
|
|
2377
|
-
|
|
2378
|
-
### `parseHtml`
|
|
2379
|
-
Type: `boolean` Default: `false`
|
|
2380
|
-
|
|
2381
|
-
Enables obfuscation of JavaScript within HTML `<script>` tags.
|
|
2382
|
-
|
|
2383
|
-
When enabled, the obfuscator will:
|
|
2384
|
-
- Auto-detect if input is HTML (by checking for `<!DOCTYPE`, `<html>`, `<head>`, `<body>`, or `<script>` tags)
|
|
2385
|
-
- Extract JavaScript from `<script>` tags marked with the `data-javascript-obfuscator` attribute
|
|
2386
|
-
- Obfuscate each marked script individually while preserving the HTML structure
|
|
2387
|
-
- Inject obfuscated code back into the original positions
|
|
2388
|
-
|
|
2389
|
-
**Important:** Only scripts with the `data-javascript-obfuscator` attribute are obfuscated. Each marked script is obfuscated individually and independently. This means:
|
|
2390
|
-
- Code inside marked script tags **must be isolated** - it must NOT reference variables, functions, or classes defined in other marked script tags
|
|
2391
|
-
- Unmarked scripts can still access globals defined by marked scripts (via `var` declarations or explicit `globalThis` assignments)
|
|
2392
|
-
- This gives you explicit control over which scripts to protect
|
|
2393
|
-
|
|
2394
|
-
**Obfuscated (must have `data-javascript-obfuscator` attribute):**
|
|
2395
|
-
- `<script data-javascript-obfuscator>` - regular scripts
|
|
2396
|
-
- `<script type="text/javascript" data-javascript-obfuscator>` - explicitly typed scripts
|
|
2397
|
-
- Scripts with any additional attributes (`id`, `class`, other `data-*`, etc.)
|
|
2398
|
-
|
|
2399
|
-
**Skipped (left unchanged):**
|
|
2400
|
-
- Scripts without `data-javascript-obfuscator` attribute
|
|
2401
|
-
- `<script type="module">` - ES modules (even with the attribute)
|
|
2402
|
-
- `<script src="...">` - external scripts (even with the attribute)
|
|
2403
|
-
- Empty script tags
|
|
2404
|
-
|
|
2405
|
-
**Note:** Source maps are not generated when `parseHtml` is enabled, as they would not map correctly to the HTML output.
|
|
2406
|
-
|
|
2407
|
-
Example:
|
|
2408
|
-
```ts
|
|
2409
|
-
// input
|
|
2410
|
-
const html = `<!DOCTYPE html>
|
|
2411
|
-
<html>
|
|
2412
|
-
<body>
|
|
2413
|
-
<!-- This script will NOT be obfuscated -->
|
|
2414
|
-
<script>
|
|
2415
|
-
var helper = 'utility';
|
|
2416
|
-
</script>
|
|
2417
|
-
|
|
2418
|
-
<!-- This script WILL be obfuscated -->
|
|
2419
|
-
<script data-javascript-obfuscator>
|
|
2420
|
-
var greeting = 'Hello World';
|
|
2421
|
-
console.log(greeting);
|
|
2422
|
-
</script>
|
|
2423
|
-
</body>
|
|
2424
|
-
</html>`;
|
|
2425
|
-
|
|
2426
|
-
JavaScriptObfuscator.obfuscate(html, {
|
|
2427
|
-
parseHtml: true,
|
|
2428
|
-
stringArray: true
|
|
2429
|
-
});
|
|
2430
|
-
|
|
2431
|
-
// output: HTML with only the marked script obfuscated
|
|
2432
|
-
```
|
|
2433
|
-
|
|
2434
|
-
### `randomIdentifiersPrefix`
|
|
2435
|
-
Type: `boolean` Default: `false`
|
|
2436
|
-
|
|
2437
|
-
Appends a seeded random prefix (6 alphanumeric characters) to all global identifiers. Use this option to avoid collisions between separately obfuscated bundles that are loaded into the same global scope — it removes the need to pick a unique `identifiersPrefix` per bundle manually.
|
|
2438
|
-
|
|
2439
|
-
- The random value is derived from the `seed` option and the source code hash, so reproducible builds with the same seed produce the same prefix.
|
|
2440
|
-
- When combined with `identifiersPrefix`, the random characters are appended to the user-provided prefix (e.g. `myApp` + random `aBc123` → `myAppaBc123`).
|
|
2441
|
-
- When combined with `vmObfuscation`, the random value replaces the default `vm` prefix — randomness already guarantees uniqueness.
|
|
2442
|
-
|
|
2443
2445
|
## Frequently Asked Questions
|
|
2444
2446
|
|
|
2445
2447
|
### What javascript versions are supported?
|