javascript-obfuscator 5.7.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 +5 -0
- package/README.md +111 -118
- package/dist/index.browser.js +3 -3
- 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/pro-api/IProApiClient.d.ts +8 -4
- package/typings/src/options/Options.d.ts +2 -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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
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
|
+
|
|
3
8
|
v5.7.0
|
|
4
9
|
---
|
|
5
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
|
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
|
|
|
@@ -1142,6 +1164,10 @@ Available values:
|
|
|
1142
1164
|
* `medium-obfuscation`;
|
|
1143
1165
|
* `high-obfuscation`.
|
|
1144
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
|
+
|
|
1145
1171
|
All addition options will be merged with selected options preset.
|
|
1146
1172
|
|
|
1147
1173
|
### `renameGlobals`
|
|
@@ -1925,8 +1951,8 @@ Specify exactly which root-level functions should get VM protection by name.
|
|
|
1925
1951
|
**Example:**
|
|
1926
1952
|
```javascript
|
|
1927
1953
|
{
|
|
1928
|
-
|
|
1929
|
-
|
|
1954
|
+
vmObfuscation: true,
|
|
1955
|
+
vmTargetFunctions: ['someFunctionName']
|
|
1930
1956
|
}
|
|
1931
1957
|
```
|
|
1932
1958
|
|
|
@@ -1940,8 +1966,8 @@ Specify root-level functions that should never get VM protection. Takes preceden
|
|
|
1940
1966
|
**Example:**
|
|
1941
1967
|
```javascript
|
|
1942
1968
|
{
|
|
1943
|
-
|
|
1944
|
-
|
|
1969
|
+
vmObfuscation: true,
|
|
1970
|
+
vmExcludeFunctions: ['someFunctionName']
|
|
1945
1971
|
}
|
|
1946
1972
|
```
|
|
1947
1973
|
|
|
@@ -1961,28 +1987,28 @@ Controls how functions/methods are selected for VM obfuscation.
|
|
|
1961
1987
|
```javascript
|
|
1962
1988
|
// Source code
|
|
1963
1989
|
function regularFunction() {
|
|
1964
|
-
|
|
1990
|
+
return 'not virtualized';
|
|
1965
1991
|
}
|
|
1966
1992
|
|
|
1967
1993
|
/* javascript-obfuscator:vm */
|
|
1968
1994
|
function sensitiveFunction() {
|
|
1969
|
-
|
|
1995
|
+
return 'this will be VM-protected';
|
|
1970
1996
|
}
|
|
1971
1997
|
|
|
1972
1998
|
function outer() {
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1999
|
+
/* javascript-obfuscator:vm */
|
|
2000
|
+
function nestedSensitive() {
|
|
2001
|
+
return 'nested but still VM-protected';
|
|
2002
|
+
}
|
|
2003
|
+
return nestedSensitive();
|
|
1978
2004
|
}
|
|
1979
2005
|
```
|
|
1980
2006
|
|
|
1981
2007
|
```javascript
|
|
1982
2008
|
// Obfuscator options
|
|
1983
2009
|
{
|
|
1984
|
-
|
|
1985
|
-
|
|
2010
|
+
vmObfuscation: true,
|
|
2011
|
+
vmTargetFunctionsMode: 'comment'
|
|
1986
2012
|
}
|
|
1987
2013
|
```
|
|
1988
2014
|
|
|
@@ -2043,6 +2069,8 @@ const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden
|
|
|
2043
2069
|
|
|
2044
2070
|
**Note:** This option only works when `vmTargetFunctionsMode` is `'root'` (the default).
|
|
2045
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
|
+
|
|
2046
2074
|
### `vmDynamicOpcodes`
|
|
2047
2075
|
Type: `boolean` Default: `false`
|
|
2048
2076
|
|
|
@@ -2057,7 +2085,7 @@ As the result - smaller output and each build looks different.
|
|
|
2057
2085
|
### `vmBytecodeEncoding`
|
|
2058
2086
|
Type: `boolean` Default: `false`
|
|
2059
2087
|
|
|
2060
|
-
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.
|
|
2061
2089
|
|
|
2062
2090
|
### `vmBytecodeArrayEncoding`
|
|
2063
2091
|
Type: `boolean` Default: `false`
|
|
@@ -2076,11 +2104,15 @@ This option externalizes the encryption key - it's not embedded in the obfuscate
|
|
|
2076
2104
|
### `vmBytecodeArrayEncodingKeyGetter`
|
|
2077
2105
|
Type: `string` Default: `''`
|
|
2078
2106
|
|
|
2079
|
-
**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).
|
|
2080
2108
|
|
|
2081
|
-
**
|
|
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.
|
|
2082
2110
|
|
|
2083
|
-
**
|
|
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.
|
|
2112
|
+
|
|
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.
|
|
2114
|
+
|
|
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.
|
|
2084
2116
|
|
|
2085
2117
|
Examples:
|
|
2086
2118
|
```ts
|
|
@@ -2098,16 +2130,19 @@ vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]
|
|
|
2098
2130
|
|
|
2099
2131
|
// From nested object
|
|
2100
2132
|
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"
|
|
2133
|
+
|
|
2134
|
+
// From backend, async (requires vmAsyncExecutor)
|
|
2135
|
+
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
|
|
2101
2136
|
```
|
|
2102
2137
|
|
|
2103
2138
|
**Usage example:**
|
|
2104
2139
|
```ts
|
|
2105
2140
|
// Build time
|
|
2106
2141
|
JavaScriptObfuscator.obfuscate(code, {
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2142
|
+
vmObfuscation: true,
|
|
2143
|
+
vmBytecodeArrayEncoding: true,
|
|
2144
|
+
vmBytecodeArrayEncodingKey: 'mySecretKey123',
|
|
2145
|
+
vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
|
|
2111
2146
|
});
|
|
2112
2147
|
|
|
2113
2148
|
// Runtime - key must be set before obfuscated code runs
|
|
@@ -2157,25 +2192,36 @@ Type: `boolean` Default: `false`
|
|
|
2157
2192
|
|
|
2158
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.
|
|
2159
2194
|
|
|
2160
|
-
### `
|
|
2195
|
+
### `vmMacroOps`
|
|
2161
2196
|
Type: `boolean` Default: `false`
|
|
2162
2197
|
|
|
2163
|
-
|
|
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.
|
|
2164
2199
|
|
|
2165
|
-
### `
|
|
2166
|
-
Type: `boolean` Default: `false`
|
|
2200
|
+
### `vmDebugProtection`
|
|
2201
|
+
Type: `boolean | object` Default: `false`
|
|
2167
2202
|
|
|
2168
|
-
|
|
2203
|
+
Adds multi-layered anti-debugging, anti-analysis, and anti-LLM defenses to the VM runtime. Works best with `browser`/`browser-no-eval` targets.
|
|
2169
2204
|
|
|
2170
|
-
|
|
2171
|
-
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:
|
|
2172
2206
|
|
|
2173
|
-
|
|
2207
|
+
```js
|
|
2208
|
+
{
|
|
2209
|
+
vmDebugProtection: {
|
|
2210
|
+
// most defenses are always on; but CDP/devtools detection is disabled
|
|
2211
|
+
inspectorDetection: false
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
```
|
|
2174
2215
|
|
|
2175
|
-
|
|
2176
|
-
|
|
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. |
|
|
2177
2221
|
|
|
2178
|
-
|
|
2222
|
+
> :bulb: The object form is available through the API
|
|
2223
|
+
|
|
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 }`.
|
|
2179
2225
|
|
|
2180
2226
|
### `vmSelfDefending`
|
|
2181
2227
|
Type: `boolean` Default: `false`
|
|
@@ -2184,12 +2230,21 @@ Adds multi-layered tamper detection, anti-hooking, and anti-reverse-engineering
|
|
|
2184
2230
|
|
|
2185
2231
|
> :warning: This option force-enables [`vmBytecodeArrayEncoding`](#vmbytecodeArrayEncoding).
|
|
2186
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
|
+
|
|
2187
2242
|
Strongly recommended to use together with [`vmDebugProtection`](#vmDebugProtection), [`vmBytecodeArrayEncodingKey`](#vmbytecodeArrayEncodingKey), and [`vmBytecodeArrayEncodingKeyGetter`](#vmbytecodeArrayEncodingKeyGetter).
|
|
2188
2243
|
|
|
2189
2244
|
### `vmDefenseHook`
|
|
2190
|
-
Type: `{ name: string, aliases?: object }` Default: `
|
|
2245
|
+
Type: `{ name: string, aliases?: object } | null` Default: `null`
|
|
2191
2246
|
|
|
2192
|
-
`vmDefenseHook`
|
|
2247
|
+
`vmDefenseHook` is `null` (disabled) or an object with two keys: **`name`** (required) and **`aliases`** (optional).
|
|
2193
2248
|
|
|
2194
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).
|
|
2195
2250
|
|
|
@@ -2249,8 +2304,6 @@ vmDefenseHook: {
|
|
|
2249
2304
|
|
|
2250
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.
|
|
2251
2306
|
|
|
2252
|
-
> A bare string (`vmDefenseHook: '__vmDetection'`) is accepted as shorthand for `{ name: '__vmDetection' }` but is **deprecated** — prefer the object form.
|
|
2253
|
-
|
|
2254
2307
|
### `vmDefenseReaction`
|
|
2255
2308
|
Type: `object` Default: `{ automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }`
|
|
2256
2309
|
|
|
@@ -2285,17 +2338,33 @@ vmDefenseReaction: { automation: 'none', domain: 'break' } // tolerate automat
|
|
|
2285
2338
|
### `browserEnvironment`
|
|
2286
2339
|
Type: `object` Default: `{}`
|
|
2287
2340
|
|
|
2288
|
-
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.
|
|
2289
2342
|
|
|
2290
|
-
|
|
2343
|
+
Fields:
|
|
2291
2344
|
|
|
2292
|
-
- **`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).
|
|
2293
2346
|
|
|
2294
2347
|
```js
|
|
2295
2348
|
browserEnvironment: { transport: 'https' }
|
|
2296
2349
|
```
|
|
2297
2350
|
|
|
2298
|
-
|
|
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.
|
|
2299
2368
|
|
|
2300
2369
|
### `vmStatefulOpcodes`
|
|
2301
2370
|
Type: `boolean` Default: `false`
|
|
@@ -2354,7 +2423,6 @@ When enabled, the string array will **only** extract strings from bytecode data
|
|
|
2354
2423
|
- When `vmBytecodeArrayEncoding: true` — top-level base64 encoded bytecode strings are extracted
|
|
2355
2424
|
- `stringArrayThreshold` still controls what percentage of those bytecode strings are extracted
|
|
2356
2425
|
|
|
2357
|
-
|
|
2358
2426
|
### `vmDomainLock`
|
|
2359
2427
|
Type: `string[]` Default: `[]`
|
|
2360
2428
|
|
|
@@ -2374,81 +2442,6 @@ Type: `string` Default: `about:blank`
|
|
|
2374
2442
|
|
|
2375
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).
|
|
2376
2444
|
|
|
2377
|
-
### `strictMode`
|
|
2378
|
-
Type: `boolean | null` Default: `null`
|
|
2379
|
-
|
|
2380
|
-
Allows to specify how the obfuscator should treat code regarding JavaScript strict mode.
|
|
2381
|
-
|
|
2382
|
-
Available values:
|
|
2383
|
-
* `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.
|
|
2384
|
-
* `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).
|
|
2385
|
-
* `false` - only explicit strict mode indicators (`'use strict'`, ES modules, class methods) are treated as strict. Parent scope inheritance still applies per JS spec.
|
|
2386
|
-
|
|
2387
|
-
### `parseHtml`
|
|
2388
|
-
Type: `boolean` Default: `false`
|
|
2389
|
-
|
|
2390
|
-
Enables obfuscation of JavaScript within HTML `<script>` tags.
|
|
2391
|
-
|
|
2392
|
-
When enabled, the obfuscator will:
|
|
2393
|
-
- Auto-detect if input is HTML (by checking for `<!DOCTYPE`, `<html>`, `<head>`, `<body>`, or `<script>` tags)
|
|
2394
|
-
- Extract JavaScript from `<script>` tags marked with the `data-javascript-obfuscator` attribute
|
|
2395
|
-
- Obfuscate each marked script individually while preserving the HTML structure
|
|
2396
|
-
- Inject obfuscated code back into the original positions
|
|
2397
|
-
|
|
2398
|
-
**Important:** Only scripts with the `data-javascript-obfuscator` attribute are obfuscated. Each marked script is obfuscated individually and independently. This means:
|
|
2399
|
-
- Code inside marked script tags **must be isolated** - it must NOT reference variables, functions, or classes defined in other marked script tags
|
|
2400
|
-
- Unmarked scripts can still access globals defined by marked scripts (via `var` declarations or explicit `globalThis` assignments)
|
|
2401
|
-
- This gives you explicit control over which scripts to protect
|
|
2402
|
-
|
|
2403
|
-
**Obfuscated (must have `data-javascript-obfuscator` attribute):**
|
|
2404
|
-
- `<script data-javascript-obfuscator>` - regular scripts
|
|
2405
|
-
- `<script type="text/javascript" data-javascript-obfuscator>` - explicitly typed scripts
|
|
2406
|
-
- Scripts with any additional attributes (`id`, `class`, other `data-*`, etc.)
|
|
2407
|
-
|
|
2408
|
-
**Skipped (left unchanged):**
|
|
2409
|
-
- Scripts without `data-javascript-obfuscator` attribute
|
|
2410
|
-
- `<script type="module">` - ES modules (even with the attribute)
|
|
2411
|
-
- `<script src="...">` - external scripts (even with the attribute)
|
|
2412
|
-
- Empty script tags
|
|
2413
|
-
|
|
2414
|
-
**Note:** Source maps are not generated when `parseHtml` is enabled, as they would not map correctly to the HTML output.
|
|
2415
|
-
|
|
2416
|
-
Example:
|
|
2417
|
-
```ts
|
|
2418
|
-
// input
|
|
2419
|
-
const html = `<!DOCTYPE html>
|
|
2420
|
-
<html>
|
|
2421
|
-
<body>
|
|
2422
|
-
<!-- This script will NOT be obfuscated -->
|
|
2423
|
-
<script>
|
|
2424
|
-
var helper = 'utility';
|
|
2425
|
-
</script>
|
|
2426
|
-
|
|
2427
|
-
<!-- This script WILL be obfuscated -->
|
|
2428
|
-
<script data-javascript-obfuscator>
|
|
2429
|
-
var greeting = 'Hello World';
|
|
2430
|
-
console.log(greeting);
|
|
2431
|
-
</script>
|
|
2432
|
-
</body>
|
|
2433
|
-
</html>`;
|
|
2434
|
-
|
|
2435
|
-
JavaScriptObfuscator.obfuscate(html, {
|
|
2436
|
-
parseHtml: true,
|
|
2437
|
-
stringArray: true
|
|
2438
|
-
});
|
|
2439
|
-
|
|
2440
|
-
// output: HTML with only the marked script obfuscated
|
|
2441
|
-
```
|
|
2442
|
-
|
|
2443
|
-
### `randomIdentifiersPrefix`
|
|
2444
|
-
Type: `boolean` Default: `false`
|
|
2445
|
-
|
|
2446
|
-
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.
|
|
2447
|
-
|
|
2448
|
-
- 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.
|
|
2449
|
-
- When combined with `identifiersPrefix`, the random characters are appended to the user-provided prefix (e.g. `myApp` + random `aBc123` → `myAppaBc123`).
|
|
2450
|
-
- When combined with `vmObfuscation`, the random value replaces the default `vm` prefix — randomness already guarantees uniqueness.
|
|
2451
|
-
|
|
2452
2445
|
## Frequently Asked Questions
|
|
2453
2446
|
|
|
2454
2447
|
### What javascript versions are supported?
|