Référence des options

Sommaire

compact

config

controlFlowFlattening

controlFlowFlatteningThreshold

deadCodeInjection

deadCodeInjectionThreshold

debugProtection

debugProtectionInterval

disableConsoleOutput

domainLock

Domaines et sous-domaines multiples

domainLockRedirectUrl

exclude

forceTransformStrings

identifierNamesCache

API Node.js

CLI

identifierNamesGenerator

identifiersDictionary

identifiersPrefix

randomIdentifiersPrefix

ignoreImports

inputFileName

log

numbersToExpressions

optionsPreset

parseHtml

renameGlobals

renameProperties

renamePropertiesMode

reservedNames

reservedStrings

seed

selfDefending

simplify

sourceMap

sourceMapBaseUrl

sourceMapFileName

sourceMapMode

sourceMapSourcesMode

splitStrings

splitStringsChunkLength

stringArray

stringArrayCallsTransform

stringArrayCallsTransformThreshold

stringArrayEncoding

stringArrayIndexesType

stringArrayIndexShift

stringArrayRotate

stringArrayShuffle

stringArrayWrappersCount

stringArrayWrappersChainedCalls

stringArrayWrappersParametersMaxCount

stringArrayWrappersType

stringArrayThreshold

strictMode

target

transformObjectKeys

warnings

vmObfuscation

vmTargetFunctions

vmExcludeFunctions

vmTargetFunctionsMode

vmForceCompileDynamicCode

vmWrapTopLevelInitializers

vmDynamicOpcodes

vmBytecodeEncoding

vmBytecodeArrayEncoding

vmBytecodeArrayEncodingKey

vmBytecodeArrayEncodingKeyGetter

vmAsyncExecutor

vmJumpsEncoding

vmMacroOps

vmDebugProtection

vmSelfDefending

vmDefenseHook

vmDefenseReaction

vmStatefulOpcodes

vmCallContextOpcodes

vmStackEncoding

vmCompactDispatcher

vmStringArrayBytecodeOnly

vmDomainLock

Domaines et sous-domaines multiples

vmDomainLockRedirectUrl

Options de préréglage

Obfuscation élevée, performances faibles

Obfuscation moyenne, performances optimales

Obfuscation faible, performances élevées

Préréglage par défaut, performances élevées

Obfuscation VM Ultra High (sécurité maximale)

VM Anti-LLM (protection contre les agents IA)

Obfuscation VM High (sécurité la plus élevée)

Obfuscation VM Medium (sécurité équilibrée)

Obfuscation VM Low (sécurité de base, meilleures performances)

VM Default (VM + protection du tableau de chaînes)

compact

Type: boolean Default: true

Sortie de code compacte sur une seule ligne.

config

Type: string Default: ``

Nom du fichier de configuration JS/JSON contenant les options de l'obfuscateur. Ces options seront remplacées par celles passées directement en ligne de commande (CLI).

controlFlowFlattening

Type: boolean Default: false

⚠️ Cette option affecte fortement les performances, jusqu'à une exécution 1,5x plus lente. Utilisez controlFlowFlatteningThreshold pour définir le pourcentage de nœuds concernés par l'aplatissement du flux de contrôle.

Active l'aplatissement du flux de contrôle du code. L'aplatissement du flux de contrôle est une transformation de la structure du code source qui en complique la compréhension.

Exemple :

// input
(function(){
    function foo () {
        return function () {
            var sum = 1 + 2;
            console.log(1);
            console.log(2);
            console.log(3);
            console.log(4);
            console.log(5);
            console.log(6);
        }
    }
    
    foo()();
})();

// output
(function () {
    function _0x3bfc5c() {
        return function () {
            var _0x3260a5 = {
                'WtABe': '4|0|6|5|3|2|1',
                'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {
                    return _0x427a8e + _0x43354c;
                }
            };
            var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;
            while (!![]) {
                switch (_0x1ad4d6[_0x1a7b12++]) {
                case '0':
                    console['log'](0x1);
                    continue;
                case '1':
                    console['log'](0x6);
                    continue;
                case '2':
                    console['log'](0x5);
                    continue;
                case '3':
                    console['log'](0x4);
                    continue;
                case '4':
                    var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);
                    continue;
                case '5':
                    console['log'](0x3);
                    continue;
                case '6':
                    console['log'](0x2);
                    continue;
                }
                break;
            }
        };
    }

	_0x3bfc5c()();
}());

controlFlowFlatteningThreshold

Type: number Default: 0.75 Min: 0 Max: 1

Probabilité que la transformation controlFlowFlattening soit appliquée à un nœud donné.

Ce paramètre est particulièrement utile pour les codes volumineux, car un grand nombre de transformations du flux de contrôle peut ralentir votre code et en augmenter la taille.

controlFlowFlatteningThreshold: 0 équivaut à controlFlowFlattening: false.

deadCodeInjection

Type: boolean Default: false

⚠️ Augmente considérablement la taille du code obfusqué (jusqu'à 200 %) ; à n'utiliser que si la taille du code obfusqué n'a pas d'importance. Utilisez deadCodeInjectionThreshold pour définir le pourcentage de nœuds concernés par l'injection de code mort.
⚠️ Cette option active de force l'option stringArray.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé.

Avec cette option, des blocs aléatoires de code mort sont ajoutés au code obfusqué.

Exemple :

// input
(function(){
    if (true) {
        var foo = function () {
            console.log('abc');
        };
        var bar = function () {
            console.log('def');
        };
        var baz = function () {
            console.log('ghi');
        };
        var bark = function () {
            console.log('jkl');
        };
        var hawk = function () {
            console.log('mno');
        };

        foo();
        bar();
        baz();
        bark();
        hawk();
    }
})();

// output
var _0x37b8 = [
    'YBCtz',
    'GlrkA',
    'urPbb',
    'abc',
    'NMIhC',
    'yZgAj',
    'zrAId',
    'EtyJA',
    'log',
    'mno',
    'jkl',
    'def',
    'Quzya',
    'IWbBa',
    'ghi'
];
function _0x43a7(_0x12cf56, _0x587376) {
    _0x43a7 = function (_0x2f87a8, _0x47eac2) {
        _0x2f87a8 = _0x2f87a8 - (0x16a7 * 0x1 + 0x5 * 0x151 + -0x1c92);
        var _0x341e03 = _0x37b8[_0x2f87a8];
        return _0x341e03;
    };
    return _0x43a7(_0x12cf56, _0x587376);
}
(function () {
    if (!![]) {
        var _0xbbe28f = function () {
            var _0x2fc85f = _0x43a7;
            if (_0x2fc85f(0xaf) === _0x2fc85f(0xae)) {
                _0x1dd94f[_0x2fc85f(0xb2)](_0x2fc85f(0xb5));
            } else {
                console[_0x2fc85f(0xb2)](_0x2fc85f(0xad));
            }
        };
        var _0x5e46bc = function () {
            var _0x15b472 = _0x43a7;
            if (_0x15b472(0xb6) !== _0x15b472(0xaa)) {
                console[_0x15b472(0xb2)](_0x15b472(0xb5));
            } else {
                _0x47eac2[_0x15b472(0xb2)](_0x15b472(0xad));
            }
        };
        var _0x3669e8 = function () {
            var _0x47a442 = _0x43a7;
            if (_0x47a442(0xb7) !== _0x47a442(0xb0)) {
                console[_0x47a442(0xb2)](_0x47a442(0xb8));
            } else {
                _0x24e0bf[_0x47a442(0xb2)](_0x47a442(0xb3));
            }
        };
        var _0x28b05a = function () {
            var _0x497902 = _0x43a7;
            if (_0x497902(0xb1) === _0x497902(0xb1)) {
                console[_0x497902(0xb2)](_0x497902(0xb4));
            } else {
                _0x59c9c6[_0x497902(0xb2)](_0x497902(0xb4));
            }
        };
        var _0x402a54 = function () {
            var _0x1906b7 = _0x43a7;
            if (_0x1906b7(0xab) === _0x1906b7(0xac)) {
                _0xb89cd0[_0x1906b7(0xb2)](_0x1906b7(0xb8));
            } else {
                console[_0x1906b7(0xb2)](_0x1906b7(0xb3));
            }
        };
        _0xbbe28f();
        _0x5e46bc();
        _0x3669e8();
        _0x28b05a();
        _0x402a54();
    }
}());

deadCodeInjectionThreshold

Type: number Default: 0.4 Min: 0 Max: 1

Permet de définir le pourcentage de nœuds concernés par deadCodeInjection.

debugProtection

Type: boolean Default: false

⚠️ Peut figer votre navigateur si vous ouvrez les outils de développement.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.

Cette option rend presque impossible l'utilisation de la fonction debugger des outils de développement (aussi bien sur les navigateurs basés sur WebKit que sur Mozilla Firefox).

debugProtectionInterval

Type: number Default: 0

⚠️ Peut figer votre navigateur ! À utiliser à vos risques et périls.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.

Si cette option est définie, un intervalle en millisecondes est utilisé pour forcer le mode débogage sur l'onglet Console, rendant plus difficile l'utilisation des autres fonctionnalités des outils de développement. Fonctionne si debugProtection est activé. La valeur recommandée est comprise entre 2000 et 4000 millisecondes.

disableConsoleOutput

Type: boolean Default: false

⚠️ Cette option désactive les appels à console de façon globale pour tous les scripts

Désactive l'utilisation de console.log, console.info, console.error, console.warn, console.debug, console.exception et console.trace en les remplaçant par des fonctions vides. Cela rend l'utilisation du débogueur plus difficile.

domainLock

Type: string[] Default: []

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Permet d'exécuter le code source obfusqué uniquement sur des domaines et/ou sous-domaines précis. Cela rend très difficile le simple copier-coller de votre code source pour l'exécuter ailleurs.

Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à l'option domainLockRedirectUrl.

Domaines et sous-domaines multiples

Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.

domainLockRedirectUrl

Type: string Default: about:blank

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par domainLock

exclude

Type: string[] Default: []

Noms de fichiers ou motifs glob indiquant les fichiers à exclure de l'obfuscation.

forceTransformStrings

Type: string[] Default: []

Force la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis.

⚠️ Cette option n'affecte que les chaînes qui ne devraient pas être transformées par stringArrayThreshold (ou d'éventuels autres seuils à l'avenir)

Cette option a priorité sur l'option reservedStrings, mais pas sur les conditional comments.

Exemple :

	{
		forceTransformStrings: [
			'some-important-value',
			'some-string_\d'
		]
	}

identifierNamesCache

Type: Object | null Default: null

L'objectif principal de cette option est de pouvoir réutiliser les mêmes noms d'identifiants lors de l'obfuscation de plusieurs sources/fichiers.

Actuellement, deux types d'identifiants sont pris en charge :

  • Identifiants globaux :
    • Tous les identifiants globaux sont écrits dans le cache ;
    • Tous les identifiants globaux non déclarés correspondants sont remplacés par les valeurs du cache.
  • Identifiants de propriété, uniquement lorsque l'option renameProperties est activée :
    • Tous les identifiants de propriété sont écrits dans le cache ;
    • Tous les identifiants de propriété correspondants sont remplacés par les valeurs du cache.

API Node.js

Si la valeur null est passée, le cache est entièrement désactivé.

Si un objet vide ({}) est passé, l'écriture des noms d'identifiants dans l'objet-cache (type TIdentifierNamesCache) est activée. Cet objet-cache est accessible via l'appel de la méthode getIdentifierNamesCache de l'objet ObfuscationResult.

L'objet-cache obtenu peut ensuite être utilisé comme valeur de l'option identifierNamesGenerator afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des sources suivantes.

Exemple :

const source1ObfuscationResult = JavaScriptObfuscator.obfuscate(
    `
        function foo(arg) {
           console.log(arg)
        }
        
        function bar() {
            var bark = 2;
        }
    `,
    {
        compact: false,
        identifierNamesCache: {},
        renameGlobals: true
    }
)

console.log(source1ObfuscationResult.getIdentifierNamesCache());
/*
    { 
        globalIdentifiers: {
            foo: '_0x5de86d',
            bar: '_0x2a943b'
        }
    }
*/



const source2ObfuscationResult = JavaScriptObfuscator.obfuscate(
    `
        // Expecting that these global functions are defined in another obfuscated file
        foo(1);
        bar();
        
        // Expecting that this global function is defined in third-party package
        baz();
    `,
    {
        compact: false,
        identifierNamesCache: source1ObfuscationResult.getIdentifierNamesCache(),
        renameGlobals: true
    }
)

console.log(source2ObfuscationResult.getObfuscatedCode());
/*
    _0x5de86d(0x1);
    _0x2a943b();
    baz();
 */

CLI

La CLI dispose d'une option différente, --identifier-names-cache-path, qui permet de définir le chemin d'un fichier .json existant servant à lire et écrire le cache des noms d'identifiants.

Si le chemin d'un fichier vide est passé, le cache des noms d'identifiants y sera écrit.

Ce fichier contenant un cache existant peut être réutilisé comme valeur de l'option --identifier-names-cache-path afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des fichiers suivants.

identifierNamesGenerator

Type: string Default: hexadecimal

Définit le générateur de noms d'identifiants.

Valeurs disponibles :

  • dictionary : noms d'identifiants issus de la liste identifiersDictionary
  • hexadecimal : noms d'identifiants du type _0xabc123
  • mangled : noms d'identifiants courts comme a, b, c
  • mangled-shuffled : identique à mangled, mais avec un alphabet mélangé

identifiersDictionary

Type: string[] Default: []

Définit le dictionnaire d'identifiants pour l'option identifierNamesGenerator : dictionary. Chaque identifiant du dictionnaire sera utilisé en plusieurs variantes, avec une casse différente pour chaque caractère. Le nombre d'identifiants du dictionnaire doit donc dépendre du nombre d'identifiants présents dans le code source d'origine.

identifiersPrefix

Type: string Default: ''

Définit un préfixe pour tous les identifiants globaux.

Utilisez cette option lorsque vous obfusquez plusieurs fichiers. Elle permet d'éviter les conflits entre les identifiants globaux de ces fichiers. Le préfixe doit être différent pour chaque fichier.

randomIdentifiersPrefix

Type: boolean Default: false

Ajoute un préfixe aléatoire dérivé de la graine (6 caractères alphanumériques) à tous les identifiants globaux. Utilisez cette option pour éviter les collisions entre des bundles obfusqués séparément et chargés dans la même portée globale — elle évite d'avoir à choisir manuellement un identifiersPrefix unique pour chaque bundle.

  • La valeur aléatoire est dérivée de l'option seed et du hash du code source ; des builds reproductibles avec la même graine produisent donc le même préfixe.
  • Combinée à identifiersPrefix, les caractères aléatoires sont ajoutés à la suite du préfixe fourni par l'utilisateur (par exemple myApp + aBc123 aléatoire → myAppaBc123).
  • Combinée à vmObfuscation, la valeur aléatoire remplace le préfixe vm par défaut — le caractère aléatoire garantit déjà l'unicité.

ignoreImports

Type: boolean Default: false

Empêche l'obfuscation des imports require. Peut être utile dans certains cas où, pour une raison ou une autre, l'environnement d'exécution exige que ces imports utilisent uniquement des chaînes statiques.

inputFileName

Type: string Default: ''

Permet de définir le nom du fichier d'entrée contenant le code source. Ce nom est utilisé en interne pour la génération de la source map. Requis lors de l'utilisation de l'API NodeJS lorsque l'option sourceMapSourcesMode a la valeur sources.

log

Type: boolean Default: false

Active la journalisation des informations dans la console.

numbersToExpressions

Type: boolean Default: false

Active la conversion des nombres en expressions.

Exemple :

// input
const foo = 1234;

// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;

optionsPreset

Type: string Default: default

Permet de définir un préréglage d'options.

Valeurs disponibles :

  • vm-default ;
  • vm-low-obfuscation ;
  • vm-medium-obfuscation ;
  • vm-high-obfuscation ;
  • vm-ultra-high-obfuscation ;
  • vm-anti-llm ;
  • default ;
  • low-obfuscation ;
  • medium-obfuscation ;
  • high-obfuscation.

Toutes les options supplémentaires seront fusionnées avec le préréglage d'options sélectionné.

parseHtml

Type: boolean Default: false

Active l'obfuscation du JavaScript contenu dans les balises HTML <script>.

Lorsqu'elle est activée, l'obfuscateur :

  • Détecte automatiquement si l'entrée est du HTML (en recherchant les balises <!DOCTYPE, <html>, <head>, <body> ou <script>)
  • Extrait le JavaScript des balises <script> marquées par l'attribut data-javascript-obfuscator
  • Obfusque chaque script marqué individuellement tout en préservant la structure HTML
  • Réinjecte le code obfusqué à ses positions d'origine

Important : seuls les scripts portant l'attribut data-javascript-obfuscator sont obfusqués. Chaque script marqué est obfusqué de façon individuelle et indépendante. Cela signifie que :

  • Le code contenu dans les balises de script marquées doit être isolé : il ne doit PAS référencer de variables, fonctions ou classes définies dans d'autres balises de script marquées
  • Les scripts non marqués peuvent tout de même accéder aux globales définies par les scripts marqués (via des déclarations var ou des affectations explicites à globalThis)
  • Cela vous donne un contrôle explicite sur les scripts à protéger

Obfusqués (doivent porter l'attribut data-javascript-obfuscator) :

  • <script data-javascript-obfuscator> - scripts ordinaires
  • <script type="text/javascript" data-javascript-obfuscator> - scripts au type explicite
  • Scripts comportant des attributs supplémentaires (id, class, autres data-*, etc.)

Ignorés (laissés inchangés) :

  • Scripts sans l'attribut data-javascript-obfuscator
  • <script type="module"> - modules ES (même avec l'attribut)
  • <script src="..."> - scripts externes (même avec l'attribut)
  • Balises de script vides

Remarque : aucune source map n'est générée lorsque parseHtml est activé, car elle ne correspondrait pas correctement à la sortie HTML.

Exemple :

// input
const html = `<!DOCTYPE html>
<html>
<body>
<!-- This script will NOT be obfuscated -->
<script>
var helper = 'utility';
</script>

<!-- This script WILL be obfuscated -->
<script data-javascript-obfuscator>
var greeting = 'Hello World';
console.log(greeting);
</script>
</body>
</html>`;

JavaScriptObfuscator.obfuscate(html, {
    parseHtml: true,
    stringArray: true
});

// output: HTML with only the marked script obfuscated

renameGlobals

Type: boolean Default: false

⚠️ cette option peut casser votre code. Ne l'activez que si vous savez ce qu'elle fait !

Active l'obfuscation des noms de variables et de fonctions globales avec déclaration.

Lorsque cette option est désactivée et que le code d'entrée déclare des fonctions ou des classes dans la portée globale (c'est-à-dire que le code n'est pas encapsulé dans une IIFE), leurs noms sont conservés tels quels dans la sortie obfusquée — d'autres scripts peuvent y faire référence par leur nom. Sous vmObfuscation, un avertissement VMGlobalFunctionNamesNotRenamed listant ces noms est signalé, car le corps de la fonction est masqué sous forme de bytecode tandis que le nom lisible de premier niveau révèle toujours ce que fait le code (par exemple à un LLM). Pour éviter cette exposition, encapsulez le code dans une IIFE ou activez cette option.

renameProperties

Type: boolean Default: false

⚠️ cette option PEUT casser votre code. Ne l'activez que si vous savez ce qu'elle fait !

Active le renommage des noms de propriétés. Toutes les propriétés DOM intégrées ainsi que les propriétés des classes JavaScript de base sont ignorées.

Pour basculer entre les modes safe et unsafe de cette option, utilisez l'option renamePropertiesMode.

Pour définir le format des noms de propriétés renommés, utilisez l'option identifierNamesGenerator.

Pour contrôler quelles propriétés seront renommées, utilisez l'option reservedNames.

Exemple :

// input
(function () {
    const foo = {
        prop1: 1,
        prop2: 2,
        calc: function () {
            return this.prop1 + this.prop2;
        }
    };
    
    console.log(foo.calc());
})();

// output
(function () {
    const _0x46529b = {
        '_0x10cec7': 0x1,
        '_0xc1c0ca': 0x2,
        '_0x4b961d': function () {
            return this['_0x10cec7'] + this['_0xc1c0ca'];
        }
    };
    console['log'](_0x46529b['_0x4b961d']());
}());

renamePropertiesMode

Type: string Default: safe

⚠️ Même en mode safe, l'option renameProperties PEUT casser votre code.

Spécifie le mode de l'option renameProperties :

  • safe - comportement par défaut depuis la version 2.11.0. Tente de renommer les propriétés de façon plus sûre afin d'éviter les erreurs d'exécution. Dans ce mode, certaines propriétés sont exclues du renommage.
  • unsafe - comportement par défaut avant la version 2.11.0. Renomme les propriétés de façon non sécurisée, sans aucune restriction.

Si un fichier utilise des propriétés d'un autre fichier, utilisez l'option identifierNamesCache pour conserver les mêmes noms de propriétés entre ces fichiers.

reservedNames

Type: string[] Default: []

Désactive l'obfuscation et la génération des identifiants correspondant aux motifs RegExp fournis.

Exemple :

	{
		reservedNames: [
			'^someVariable',
			'functionParameter_\d'
		]
	}

reservedStrings

Type: string[] Default: []

Désactive la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis. Les chaînes correspondantes resteront visibles dans la sortie obfusquée.

Avec l'obfuscation VM, les chaînes réservées sont stockées dans un tableau distinct non chiffré afin de rester visibles. C'est utile pour les chaînes qui doivent rester lisibles, comme les points de terminaison d'API pour la supervision ou les identifiants de bibliothèques.

Exemple :

	{
		reservedStrings: [
			'react-native',
			'\.\/src\/test',
			'some-string_\d'
		]
	}

seed

Type: string|number Default: 0

Cette option définit la graine du générateur aléatoire. C'est utile pour obtenir des résultats reproductibles.

Si la graine vaut 0, le générateur aléatoire fonctionne sans graine.

selfDefending

Type: boolean Default: false

⚠️ Ne modifiez d'aucune façon le code obfusqué après l'obfuscation avec cette option, car toute modification comme une minification du code peut déclencher l'auto-défense et le code cessera de fonctionner !
⚠️ Cette option force la valeur compact à true
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmSelfDefending.

Cette option rend le code de sortie résistant à la mise en forme et au renommage des variables. Si l'on tente d'utiliser un embellisseur JavaScript sur le code obfusqué, celui-ci cessera de fonctionner, ce qui le rend plus difficile à comprendre et à modifier.

simplify

Type: boolean Default: true

Active une obfuscation supplémentaire du code par simplification.

⚠️ dans les prochaines versions, l'obfuscation des littéraux boolean (true => !![]) sera déplacée sous cette option.

Exemple :

// input
if (condition1) {
    const foo = 1;
    const bar = 2;
  
    console.log(foo);
  
    return bar;
} else if (condition2) {
    console.log(1);
    console.log(2);
    console.log(3);
  
    return 4;
} else {
    return 5;
}

// output
if (condition1) {
    const foo = 0x1, bar = 0x2;
    return console['log'](foo), bar;
} else
    return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;

sourceMap

Type: boolean Default: false

Active la génération d'une source map pour le code obfusqué.

Les source maps peuvent vous aider à déboguer votre code source JavaScript obfusqué. Si vous souhaitez ou devez déboguer en production, vous pouvez téléverser le fichier de source map distinct vers un emplacement secret, puis y diriger votre navigateur.

sourceMapBaseUrl

Type: string Default: ``

Définit l'URL de base de l'URL d'import de la source map lorsque sourceMapMode: 'separate'.

Exemple en CLI :

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'

Résultat :

//# sourceMappingURL=http://localhost:9000/out.js.map

sourceMapFileName

Type: string Default: ``

Définit le nom du fichier de sortie de la source map lorsque sourceMapMode: 'separate'.

Exemple en CLI :

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example

Résultat :

//# sourceMappingURL=http://localhost:9000/example.js.map

sourceMapMode

Type: string Default: separate

Spécifie le mode de génération de la source map :

  • inline - ajoute la source map à la fin de chaque fichier .js ;
  • separate - génère un fichier '.map' correspondant contenant la source map. Si vous exécutez l'obfuscateur via la CLI, un lien vers le fichier de source map est ajouté à la fin du fichier de code obfusqué : //# sourceMappingUrl=file.js.map.

sourceMapSourcesMode

Type: string Default: sources-content

Permet de contrôler les champs sources et sourcesContent de la source map :

  • sources-content - ajoute un champ sources factice et un champ sourcesContent contenant le code source d'origine ;
  • sources - ajoute un champ sources avec une description de source valide, sans ajouter de champ sourcesContent. Avec l'API NodeJS, il est nécessaire de définir l'option inputFileName, qui sera utilisée comme valeur du champ sources.

splitStrings

Type: boolean Default: false

Découpe les chaînes littérales en morceaux dont la longueur correspond à la valeur de l'option splitStringsChunkLength.

Exemple :

// input
(function(){
    var test = 'abcdefg';
})();

// output
(function(){
    var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();

splitStringsChunkLength

Type: number Default: 10

Définit la longueur des morceaux de l'option splitStrings.

stringArray

Type: boolean Default: true

Retire les littéraux de chaîne et les place dans un tableau spécial. Par exemple, la chaîne "Hello World" dans var m = "Hello World"; sera remplacée par quelque chose comme var m = _0x12c456[0x1];

stringArrayCallsTransform

Type: boolean Default: false

⚠️ l'option stringArray doit être activée

Active la transformation des appels au stringArray. Tous les arguments de ces appels peuvent être extraits vers un autre objet selon la valeur de stringArrayCallsTransformThreshold. Cela rend encore plus difficile la détection automatique des appels au tableau de chaînes.

Exemple :

function foo() {
    var k = {
        c: 0x2f2,
        d: '0x396',
        e: '0x397',
        f: '0x39a',
        g: '0x39d',
        h: 0x398,
        l: 0x394,
        m: '0x39b',
        n: '0x39f',
        o: 0x395,
        p: 0x395,
        q: 0x399,
        r: '0x399'
    };
    var c = i(k.d, k.e);
    var d = i(k.f, k.g);
    var e = i(k.h, k.l);
    var f = i(k.m, k.n);
    function i(c, d) {
        return b(c - k.c, d);
    }
    var g = i(k.o, k.p);
    var h = i(k.q, k.r);
}
function j(c, d) {
    var l = { c: 0x14b };
    return b(c - -l.c, d);
}
console[j(-'0xa6', -'0xa6')](foo());
function b(c, d) {
    var e = a();
    b = function (f, g) {
        f = f - 0xa3;
        var h = e[f];
        return h;
    };
    return b(c, d);
}
function a() {
    var m = [
        'string5',
        'string1',
        'log',
        'string3',
        'string6',
        'string2',
        'string4'
    ];
    a = function () {
        return m;
    };
    return a();
}

stringArrayCallsTransformThreshold

Type: number Default: 0.5

⚠️ les options stringArray et stringArrayCallsTransformThreshold doivent être activées

Ce paramètre permet d'ajuster la probabilité (de 0 à 1) que les appels au tableau de chaînes soient transformés.

stringArrayEncoding

Type: string[] Default: []

⚠️ l'option stringArray doit être activée

Cette option peut ralentir votre script.

Encode tous les littéraux de chaîne du stringArray à l'aide de base64 ou rc4 et insère un code spécial servant à les décoder à l'exécution.

Chaque valeur du stringArray sera encodée selon un encodage choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs encodages.

Valeurs disponibles :

  • 'none' (boolean) : n'encode pas la valeur du stringArray
  • 'base64' (string) : encode la valeur du stringArray avec base64
  • 'rc4' (string) : encode la valeur du stringArray avec rc4. Environ 30 à 50 % plus lent que base64, mais rend plus difficile la récupération des valeurs initiales.

Par exemple, avec les valeurs d'option suivantes, certaines valeurs du stringArray ne seront pas encodées, et d'autres seront encodées avec base64 et rc4 :

stringArrayEncoding: [
    'none',
    'base64',
    'rc4'
]

stringArrayIndexesType

Type: string[] Default: ['hexadecimal-number']

⚠️ l'option stringArray doit être activée

Permet de contrôler le type des index d'appel au tableau de chaînes.

Chaque index d'appel au stringArray sera transformé selon un type choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs types.

Valeurs disponibles :

  • 'hexadecimal-number' (default) : transforme les index d'appel au tableau de chaînes en nombres hexadécimaux
  • 'hexadecimal-numeric-string' : transforme les index d'appel au tableau de chaînes en chaînes numériques hexadécimales

Avant la version 2.9.0, javascript-obfuscator transformait tous les index d'appel au tableau de chaînes avec le type hexadecimal-numeric-string. Cela rend la déobfuscation manuelle légèrement plus difficile, mais permet une détection facile de ces appels par les déobfuscateurs automatiques.

Le nouveau type hexadecimal-number vise à rendre plus difficile la détection automatique des motifs d'appel au tableau de chaînes dans le code.

D'autres types seront ajoutés à l'avenir.

stringArrayIndexShift

Type: boolean Default: true

⚠️ l'option stringArray doit être activée

Active un décalage d'index supplémentaire pour tous les appels au tableau de chaînes

stringArrayRotate

Type: boolean Default: true

⚠️ stringArray doit être activé

Décale le tableau stringArray d'un nombre de positions fixe et aléatoire (généré lors de l'obfuscation du code). Cela rend plus difficile la mise en correspondance de l'ordre des chaînes retirées avec leur emplacement d'origine.

stringArrayShuffle

Type: boolean Default: true

⚠️ stringArray doit être activé

Mélange aléatoirement les éléments du tableau stringArray.

stringArrayWrappersCount

Type: number Default: 1

⚠️ l'option stringArray doit être activée

Définit le nombre de wrappers du string array dans chaque portée racine ou de fonction. Le nombre réel de wrappers dans chaque portée est limité par le nombre de nœuds literal présents dans cette portée.

Exemple :

// Input
const foo = 'foo';
const bar = 'bar';
        
function test () {
    const baz = 'baz';
    const bark = 'bark';
    const hawk = 'hawk';
}

const eagle = 'eagle';

// Output, stringArrayWrappersCount: 5
const _0x3f6c = [
    'bark',
    'bar',
    'foo',
    'eagle',
    'hawk',
    'baz'
];
const _0x48f96e = _0x2e13;
const _0x4dfed8 = _0x2e13;
const _0x55e970 = _0x2e13;
function _0x2e13(_0x33c4f5, _0x3f6c62) {
    _0x2e13 = function (_0x2e1388, _0x60b1e) {
        _0x2e1388 = _0x2e1388 - 0xe2;
        let _0x53d475 = _0x3f6c[_0x2e1388];
        return _0x53d475;
    };
    return _0x2e13(_0x33c4f5, _0x3f6c62);
}
const foo = _0x48f96e(0xe4);
const bar = _0x4dfed8(0xe3);
function test() {
    const _0x1c262f = _0x2e13;
    const _0x54d7a4 = _0x2e13;
    const _0x5142fe = _0x2e13;
    const _0x1392b0 = _0x1c262f(0xe7);
    const _0x201a58 = _0x1c262f(0xe2);
    const _0xd3a7fb = _0x1c262f(0xe6);
}
const eagle = _0x48f96e(0xe5);

stringArrayWrappersChainedCalls

Type: boolean Default: true

⚠️ les options stringArray et stringArrayWrappersCount doivent être activées

Active les appels chaînés entre les wrappers du string array.

Exemple :

// Input
const foo = 'foo';
const bar = 'bar';
        
function test () {
    const baz = 'baz';
    const bark = 'bark';

    function test1() {
        const hawk = 'hawk';
        const eagle = 'eagle';
    } 
}

// Output, stringArrayWrappersCount: 5, stringArrayWrappersChainedCalls: true
const _0x40c2 = [
    'bar',
    'bark',
    'hawk',
    'eagle',
    'foo',
    'baz'
];
const _0x31c087 = _0x3280;
const _0x31759a = _0x3280;
function _0x3280(_0x1f52ee, _0x40c2a2) {
    _0x3280 = function (_0x3280a4, _0xf07b02) {
        _0x3280a4 = _0x3280a4 - 0x1c4;
        let _0x57a182 = _0x40c2[_0x3280a4];
        return _0x57a182;
    };
    return _0x3280(_0x1f52ee, _0x40c2a2);
}
const foo = _0x31c087(0x1c8);
const bar = _0x31c087(0x1c4);
function test() {
    const _0x848719 = _0x31759a;
    const _0x2693bf = _0x31c087;
    const _0x2c08e8 = _0x848719(0x1c9);
    const _0x359365 = _0x2693bf(0x1c5);
    function _0x175e90() {
        const _0x310023 = _0x848719;
        const _0x2302ef = _0x2693bf;
        const _0x237437 = _0x310023(0x1c6);
        const _0x56145c = _0x310023(0x1c7);
    }
}

stringArrayWrappersParametersMaxCount

Type: number Default: 2

⚠️ l'option stringArray doit être activée
⚠️ Actuellement, cette option n'affecte que les wrappers ajoutés par la valeur function de l'option stringArrayWrappersType

Permet de contrôler le nombre maximal de paramètres des wrappers du tableau de chaînes. La valeur par défaut et minimale est 2. Valeur recommandée entre 2 et 5.

stringArrayWrappersType

Type: string Default: variable

⚠️ les options stringArray et stringArrayWrappersCount doivent être activées

Permet de sélectionner le type des wrappers ajoutés par l'option stringArrayWrappersCount.

Valeurs disponibles :

  • 'variable' : ajoute des wrappers de type variable en haut de chaque portée. Performances rapides.
  • 'function' : ajoute des wrappers de type fonction à des positions aléatoires dans chaque portée. Performances plus lentes qu'avec variable, mais offre une obfuscation plus stricte.

Il est fortement recommandé d'utiliser les wrappers function pour une obfuscation plus poussée lorsque la perte de performances n'a pas d'impact important sur l'application obfusquée.

Exemple avec la valeur 'function' :

// input
const foo = 'foo';

function test () {
    const bar = 'bar';
    console.log(foo, bar);
}

test();

// output
const a = [
    'log',
    'bar',
    'foo'
];
const foo = d(0x567, 0x568);
function b(c, d) {
    b = function (e, f) {
        e = e - 0x185;
        let g = a[e];
        return g;
    };
    return b(c, d);
}
function test() {
    const c = e(0x51c, 0x51b);
    function e (c, g) {
        return b(c - 0x396, g);
    }
    console[f(0x51b, 0x51d)](foo, c);
    function f (c, g) {
        return b(c - 0x396, g);
    }
}
function d (c, g) {
    return b(g - 0x3e1, c);
}
test();

stringArrayThreshold

Type: number Default: 0.8 Min: 0 Max: 1

⚠️ l'option stringArray doit être activée

Ce paramètre permet d'ajuster la probabilité (de 0 à 1) qu'un littéral de chaîne soit inséré dans le stringArray.

Ce paramètre est particulièrement utile pour les codes volumineux, car il génère de nombreux appels au string array et peut ralentir votre code.

stringArrayThreshold: 0 équivaut à stringArray: false.

strictMode

Type: boolean | null Default: null

Permet de spécifier la façon dont l'obfuscateur traite le code vis-à-vis du mode strict de JavaScript.

Valeurs disponibles :

  • null (par défaut) - détecte automatiquement le mode strict à partir du code. Si le code contient une directive 'use strict' explicite, une syntaxe de module ES ou des méthodes de classe, il est traité en mode strict. Sinon, le mode non strict (sloppy) est supposé.
  • true - force le traitement en mode strict pour tout le code, même sans directive 'use strict' explicite. À utiliser lorsque votre code s'exécutera dans un contexte de mode strict (par exemple dans des modules ES, des bundlers ou des frameworks modernes).
  • false - seuls les indicateurs de mode strict explicites ('use strict', modules ES, méthodes de classe) sont traités comme du mode strict. L'héritage de la portée parente s'applique toujours conformément à la spécification JS.

target

Type: string Default: browser

Permet de définir l'environnement cible du code obfusqué.

Valeurs disponibles :

  • browser (par défaut) — environnement de page web standard. Le code produit est identique à celui de node, mais certaines options propres au navigateur ne peuvent pas être utilisées avec la cible node
  • browser-no-eval — identique à browser, mais la sortie n'utilise pas eval(). À utiliser lorsque la page cible applique une Content Security Policy qui interdit eval/unsafe-eval.
  • node — environnement Node.js. Les options propres au navigateur sont désactivées (elles requièrent window/document et seraient sans effet ou lèveraient une erreur sous Node). Certaines défenses vmSelfDefending qui reposent sur des API exclusivement navigateur — détection de navigateur headless, restauration d'un realm propre via iframe, contrôles anti-inspecteur/DOM — ne sont pas générées pour cette cible.
  • service-worker — contexte Service Worker. Pas de window, pas de document, un global self différent.
  • userscript — bac à sable d'un gestionnaire de userscripts (Tampermonkey, par exemple). Les défenses vmSelfDefending sont ajustées en conséquence.
  • bytenode — code Node.js qui sera compilé avec le chargeur bytenode (bytecode V8 mis en cache .jsc) après l'obfuscation. L'obfuscateur lui-même n'invoque pas bytenode ; il produit un JavaScript obfusqué par VM dont le runtime est structuré pour survivre à l'étape de compilation de bytenode, et les défenses vmSelfDefending sont ajustées en conséquence. Exécutez vous-même bytenode sur la sortie obfusquée pour produire le fichier .jsc final.

transformObjectKeys

Type: boolean Default: false

Active la transformation des clés d'objet.

Exemple :

// input
(function(){
    var object = {
        foo: 'test1',
        bar: {
            baz: 'test2'
        }
    };
})();

// output
var _0x4735 = [
    'foo',
    'baz',
    'bar',
    'test1',
    'test2'
];
function _0x390c(_0x33d6b6, _0x4735f4) {
    _0x390c = function (_0x390c37, _0x1eed85) {
        _0x390c37 = _0x390c37 - 0x198;
        var _0x2275f8 = _0x4735[_0x390c37];
        return _0x2275f8;
    };
    return _0x390c(_0x33d6b6, _0x4735f4);
}
(function () {
    var _0x17d1b7 = _0x390c;
    var _0xc9b6bb = {};
    _0xc9b6bb[_0x17d1b7(0x199)] = _0x17d1b7(0x19c);
    var _0x3d959a = {};
    _0x3d959a[_0x17d1b7(0x198)] = _0x17d1b7(0x19b);
    _0x3d959a[_0x17d1b7(0x19a)] = _0xc9b6bb;
    var _0x41fd86 = _0x3d959a;
}());

warnings

Type: string | object Default: all

Contrôle quels avertissements d'obfuscation non fatals sont émis via la méthode ObfuscationResult.getWarnings().

Valeurs disponibles :

  • 'all' (par défaut) — chaque avertissement est émis.
  • 'none' — tous les avertissements sont supprimés.
  • un objet associant des types d'avertissement à des booléens — un type associé à false est supprimé ; tout type absent (ou associé à true) reste actif. Par exemple, { "VMGlobalFunctionNamesNotRenamed": false } conserve tous les avertissements sauf celui-ci.

Types d'avertissement :

  • VMGlobalFunctionNamesNotRenamed — sous vmObfuscation, les noms des déclarations de fonctions de premier niveau, des déclarations de classes et des variables auxquelles est affectée une expression de fonction/fléchée/classe ont été conservés tels quels (l'option renameGlobals est désactivée et le code n'est pas encapsulé dans une IIFE) ; ils restent donc lisibles dans la sortie même si les corps sont masqués sous forme de bytecode. Les noms exportés ne sont pas signalés.
  • VMTopLevelInitializerNotVirtualized — des initialiseurs de variables de premier niveau sont restés en JavaScript ordinaire sous obfuscation VM parce que vmWrapTopLevelInitializers est désactivé ou n'a pas pu les virtualiser.
  • DynamicCodeRenameRisk — le code construit une fonction à partir d'une chaîne à l'exécution (eval direct, constructeur Function, ou fn.toString() injecté dans un <script>/Worker), ce qui peut référencer des identifiants que l'obfuscateur a renommés.
  • VMDynamicCodeSkipped — une fonction a été exclue du bytecoding VM parce qu'elle contient un eval direct / un new Function dynamique / Function (voir vmForceCompileDynamicCode).
  • VMSyncFunctionSkippedInAsyncMode — avec vmAsyncExecutor activé, une fonction que vous aviez explicitement marquée en mode comment s'est avérée synchrone et a été ignorée (seules les fonctions asynchrones sont virtualisées dans ce mode).
  • VMAsyncGeneratorSkippedInAsyncMode — avec vmAsyncExecutor et un getter de clé asynchrone actif, un générateur asynchrone marqué n'a pas pu être virtualisé (il doit renvoyer son itérateur de façon synchrone).
  • BrowserTargetWithNodeStyleCode — le code semble cibler Node.js (par exemple require('fs'), __dirname, process.argv) alors que l'option target est réglée sur un environnement de type navigateur.

vmObfuscation

Type: boolean Default: false

Active l'obfuscation en bytecode basée sur une VM. Lorsqu'elle est activée, les fonctions JavaScript sont compilées en bytecode sur mesure qui s'exécute sur une machine virtuelle embarquée. Cela offre le plus haut niveau de protection, car la logique du code d'origine est entièrement transformée.

Exemple : Un code lisible comme return qty * price devient une liste de nombres comme [0x15,0x03,0x17,...] que seul l'interpréteur VM embarqué peut exécuter. La logique d'origine n'est plus visible sous forme de JavaScript.

vmTargetFunctions

Type: string[] Default: []

Indique précisément, par leur nom, quelles fonctions de premier niveau doivent bénéficier de la protection VM.

Exemple :

{
    vmObfuscation: true,
    vmTargetFunctions: ['someFunctionName']
}

Résultat : seules ces trois fonctions sont protégées par VM. Tout le reste demeure du JavaScript ordinaire (mais toujours obfusqué). Idéal pour protéger des vérifications de licence sensibles ou une logique d'authentification tout en gardant le reste de votre code léger.

vmExcludeFunctions

Type: string[] Default: []

Indique les fonctions de premier niveau qui ne doivent jamais bénéficier de la protection VM. Cette option a priorité sur les autres réglages.

Exemple :

{
    vmObfuscation: true,
    vmExcludeFunctions: ['someFunctionName']
}

Quand l'utiliser : les fonctions de premier niveau critiques pour les performances (boucles d'animation, traitement de données en temps réel) peuvent être exclues afin d'éviter la surcharge de la VM tout en protégeant tout le reste.

vmTargetFunctionsMode

Type: string Default: root

Contrôle la façon dont les fonctions/méthodes sont sélectionnées pour l'obfuscation VM.

ModeDescription
rootComportement par défaut. Seules les fonctions de premier niveau sont prises en compte pour l'obfuscation VM. Utilise la liste d'autorisation vmTargetFunctions et la liste d'exclusion vmExcludeFunctions pour filtrer.
commentSeules les fonctions/méthodes annotées du commentaire /* javascript-obfuscator:vm */ sont obfusquées par VM. Fonctionne avec les fonctions/méthodes à tout niveau d'imbrication.

Exemple - mode Comment :

// Source code
function regularFunction() {
    return 'not virtualized';
}

/* javascript-obfuscator:vm */
function sensitiveFunction() {
    return 'this will be VM-protected';
}

function outer() {
    /* javascript-obfuscator:vm */
    function nestedSensitive() {
        return 'nested but still VM-protected';
    }
    return nestedSensitive();
}
// Obfuscator options
{
    vmObfuscation: true,
    vmTargetFunctionsMode: 'comment'
}

Quand l'utiliser : lorsque vous avez besoin d'un contrôle chirurgical sur les fonctions qui bénéficient de la protection VM, en particulier des fonctions imbriquées contenant une logique sensible. Contrairement à vmTargetFunctions, qui ne fonctionne qu'avec des fonctions nommées de premier niveau, le mode comment vous permet de protéger n'importe quelle fonction, où qu'elle se trouve dans votre code.

vmForceCompileDynamicCode

Type: boolean Default: false

Contrôle ce que l'obfuscation VM fait d'une fonction contenant un appel direct à eval, new Function(...) ou Function(...).

Par défaut, une telle fonction (ainsi que toutes les fonctions qui y sont définies) est exclue du bytecoding VM et un avertissement VMDynamicCodeSkipped est signalé via result.getWarnings(). En effet, le source construit à l'exécution peut référencer des identifiants de la chaîne de portées environnante — des identifiants que l'obfuscateur a renommés.

Lorsqu'elle vaut true, la fonction est tout de même convertie en bytecode et l'avertissement VMDynamicCodeSkipped n'est plus émis.

L'avertissement distinct DynamicCodeRenameRisk continue de se déclencher quelle que soit cette option, car le risque de renommage qu'il décrit est indépendant de l'exclusion VM — activer cette option ne rend pas le motif sous-jacent plus sûr pour autant.

// Source code
function loadConfig(src) {
    return eval(src);
}
loadConfig('1 + 2');
// Options
{
    vmObfuscation: true,
    vmForceCompileDynamicCode: true
}

Avec l'option désactivée (par défaut), loadConfig reste en JavaScript ordinaire. Avec l'option activée, loadConfig est compilée en bytecode VM comme n'importe quelle autre fonction. Utilisez-la lorsque vous avez audité le site d'appel et que vous savez que le code construit à l'exécution ne dépend pas d'identifiants renommés par une closure.

vmWrapTopLevelInitializers

Type: boolean Default: false

Encapsule certains initialiseurs de variables de premier niveau dans des IIFE (expressions de fonction immédiatement invoquées) afin qu'ils puissent être obfusqués par VM.

Ce qu'elle fait : Sans cette option, les constantes et variables de premier niveau restent visibles dans la sortie :

// Input
const MY_STRING = "my-string";

// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string";  // String is visible!

Avec cette option activée, l'initialiseur est encapsulé dans une IIFE qui est obfusquée par VM :

// Input
const MY_STRING = "my-string";

// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })();  // String hidden in bytecode

Remarque : cette option ne fonctionne que lorsque vmTargetFunctionsMode vaut 'root' (la valeur par défaut).

Avertissements : chaque fois qu'un initialiseur de premier niveau se retrouve en JavaScript ordinaire sous obfuscation VM, un avertissement VMTopLevelInitializerNotVirtualized listant les noms des variables concernées est signalé. Cela couvre : cette option désactivée, les initialiseurs que cette option a dû ignorer (chacun accompagné de sa raison — par exemple l'initialiseur référence un déclarateur voisin ou contient un await de premier niveau), et le mode vmAsyncExecutor où les wrappers synchrones ne peuvent pas du tout être virtualisés.

vmDynamicOpcodes

Type: boolean Default: false

Rend l'interpréteur VM plus petit et unique à chaque build.

Ce qu'elle fait :

  1. Filtre les instructions inutilisées - Si votre code n'utilise pas de classes, les instructions liées aux classes sont entièrement supprimées
  2. Rend la structure aléatoire - L'ordre des gestionnaires d'instructions est mélangé à chaque build

En conséquence, la sortie est plus petite et chaque build a une apparence différente.

vmBytecodeEncoding

Type: boolean Default: false

Encode chaque instruction du bytecode. Les instructions sont décodées une par une pendant l'exécution.

vmBytecodeArrayEncoding

Type: boolean Default: false

Encode l'intégralité du tableau de bytecode en un seul bloc. Le tableau est décodé une seule fois au démarrage, avant le début de l'exécution. À utiliser conjointement avec vmBytecodeEncoding pour obtenir deux couches de protection.

vmBytecodeArrayEncodingKey

Type: string Default: ''

Clé de chiffrement personnalisée pour l'encodage du tableau de bytecode. Lorsqu'elle est définie, cette clé est utilisée à la place de la clé par défaut dérivée de l'environnement. La clé doit être fournie à l'exécution via vmBytecodeArrayEncodingKeyGetter.

Cette option externalise la clé de chiffrement : elle n'est pas intégrée au code obfusqué lui-même. Bien que la clé reste accessible à l'exécution (et ne soit donc pas véritablement secrète), cette séparation empêche les outils d'analyse statique de retrouver la clé en examinant le seul code.

Important : la clé doit être disponible de façon synchrone au chargement du code obfusqué. Utilisez un stockage synchrone comme les cookies, localStorage, sessionStorage, des variables globales ou des éléments du DOM (par exemple des balises meta injectées par le serveur). Les méthodes asynchrones comme fetch() ne peuvent pas être utilisées directement dans l'expression du getter de clé.

vmBytecodeArrayEncodingKeyGetter

Type: string Default: ''

Expression JavaScript synchrone qui renvoie la clé de chiffrement à l'exécution. Cette expression est évaluée au chargement du code obfusqué et doit renvoyer la même clé que celle fournie dans vmBytecodeArrayEncodingKey. Pour résoudre la clé de façon asynchrone (une Promise), activez vmAsyncExecutor.

Remarque : un getter renvoyant une Promise nécessite vmAsyncExecutor. Cela ne peut pas être vérifié au moment du build ; un getter renvoyant une Promise avec vmAsyncExecutor désactivé échoue donc à l'exécution — le décodeur reçoit la Promise au lieu de la clé.

Le code obfusqué ne fonctionne que si le getter de clé renvoie exactement la même clé que celle utilisée lors de l'obfuscation. Si les clés ne correspondent pas, le déchiffrement échoue et le code produit des résultats erronés ou des erreurs. Si le getter de clé renvoie undefined, null ou une chaîne vide, le code lève une erreur : "VM decryption key not available".

Important : ne conservez pas la clé dans le même fichier/script que le code obfusqué — l'y intégrer permet à un simple examen statique du bundle de la retrouver. Stockez-la plutôt dans une source distincte : cookies définis par le serveur, localStorage renseigné par un autre script, balise meta HTML injectée par le serveur, variable globale définie par un autre script, ou (avec vmAsyncExecutor) récupérée depuis votre backend à l'exécution.

Lorsque la clé est récupérée depuis votre backend (via vmAsyncExecutor), ajoutez des contrôles fondés sur la session ou l'origine sur ce point de terminaison : renvoyez la bonne clé aux utilisateurs réels (session valide, Origin/Referer attendus) et une clé factice aux requêtes suspectes (par exemple une origine localhost/inattendue, absence de session). Les utilisateurs réels s'exécutent normalement ; une copie exécutée en dehors de votre environnement obtient une clé qui ne déchiffre rien. La logique exacte dépend de votre site.

Exemples :

// From cookie
vmBytecodeArrayEncodingKeyGetter: "document.cookie.match(/vmKey=([^;]+)/)?.[1]"

// From localStorage
vmBytecodeArrayEncodingKeyGetter: "localStorage.getItem('vmKey')"

// From global variable
vmBytecodeArrayEncodingKeyGetter: "window.__VM_KEY__"

// From meta tag (server-injected)
vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]').content"

// From nested object
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"

// From backend, async (requires vmAsyncExecutor)
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'

Exemple d'utilisation :

// Build time
JavaScriptObfuscator.obfuscate(code, {
    vmObfuscation: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: 'mySecretKey123',
    vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
});

// Runtime - key must be set before obfuscated code runs
window.__VM_KEY__ = 'mySecretKey123';

vmAsyncExecutor

Type: boolean Default: false

Active l'exécuteur VM asynchrone, qui permet à vmBytecodeArrayEncodingKeyGetter de renvoyer une Promise (un getter de clé asynchrone) — la clé de déchiffrement peut ainsi être récupérée à l'exécution (requête réseau, IndexedDB, etc.) au lieu de devoir être disponible de façon synchrone au chargement du code.

Fortement recommandé pour les bases de code entièrement asynchrones. Dans ce mode, seules les fonctions async sont virtualisées — une fonction synchrone ne peut pas être rendue asynchrone sans transformer sa valeur de retour en Promise et casser ses appelants — de sorte qu'un code async de bout en bout obtient la meilleure couverture. Cela fonctionne tout de même lorsque la racine est synchrone (par exemple une IIFE synchrone / un wrapper UMD) : les fonctions async les plus externes qu'elle contient sont protégées, et les parties synchrones sont laissées telles quelles.

Ce qui est transformé : chaque fonction async la plus externe, où qu'elle apparaisse (y compris imbriquée dans des wrappers synchrones). L'async la plus externe de chaque chaîne est l'unité protégée — tout ce qu'elle contient, synchrone comme asynchrone, y est compilé. Les fonctions synchrones et les générateurs simples restent non obfusqués.

function foo() {              // sync — left as-is
    function bar() {}         // sync — left as-is

    async function baz() {    // transformed
        // any code here, including calls to other async or sync functions
    }

    async function bark() {   // transformed
        // any code here, including calls to other async or sync functions
    }
}

Exclusions et avertissements. Les générateurs asynchrones restent eux aussi non obfusqués lorsqu'un getter de clé asynchrone est actif (un générateur asynchrone doit renvoyer son itérateur de façon synchrone et ne peut pas attendre la clé). Dans le mode par défaut vmTargetFunctionsMode: 'root', les exclusions sont silencieuses (la sélection est automatique) ; en mode comment, un avertissement est émis via ObfuscationResult.getWarnings() chaque fois qu'une fonction que vous avez explicitement marquée ne peut pas être virtualisée — elle s'est avérée synchrone, ou il s'agit d'un générateur asynchrone sous un getter de clé asynchrone.

Le getter de clé asynchrone nécessite en outre vmBytecodeArrayEncoding avec un vmBytecodeArrayEncodingKeyGetter.

Exemple d'utilisation :

JavaScriptObfuscator.obfuscate(code, {
    vmObfuscation: true,
    vmAsyncExecutor: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: 'mySecretKey123',
    // the key getter may now return a Promise
    vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
});

vmJumpsEncoding

Type: boolean Default: false

Encode les cibles de saut dans le bytecode. Les décalages de saut sont calculés à l'exécution, masquant la structure du flux de contrôle (if/else, boucles, etc.) à l'analyse statique.

vmMacroOps

Type: boolean Default: false

Combine des séquences d'instructions courantes en opcodes « macro » uniques. Par exemple, LOAD + ADD + STORE peut devenir une seule instruction MACRO_ADD_TO_VAR. Cela déjoue la reconnaissance de motifs et peut améliorer les performances.

vmDebugProtection

Type: boolean Default: false

Ajoute au runtime de la VM des défenses multicouches anti-débogage, anti-analyse et anti-LLM. Fonctionne au mieux avec les cibles browser/browser-no-eval.

vmSelfDefending

Type: boolean Default: false

Ajoute au runtime de la VM une protection multicouche de détection des altérations, anti-hooking et anti-rétro-ingénierie.

⚠️ Cette option active de force vmBytecodeArrayEncoding.

⚠️ Détection d'environnements sensibles. Cette option lie le code obfusqué à son environnement d'exécution cible et utilise un fingerprinting avancé du navigateur pour détecter les outils d'automatisation. Un code protégé par cette option se cassera intentionnellement lorsqu'il sera exécuté dans :

  • Des navigateurs headless (Chrome/Chromium headless, PhantomJS)
  • Des outils d'automatisation de navigateur (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
  • Node.js (lorsque target vaut browser)
  • jsdom ou d'autres émulations du DOM côté serveur
  • Des environnements où des fonctions natives du navigateur ont été hookées ou remplacées

Le code fonctionnera correctement dans les navigateurs classiques (Chrome, Firefox, Safari, Edge), y compris lorsqu'il est chargé dans des iframes, des extensions de navigateur (content scripts) et des Web Workers. Si vous devez exécuter des tests automatisés sur du code protégé, désactivez vmSelfDefending pour les builds de test — cette option est conçue pour empêcher l'analyse automatisée et ne peut pas être utilisée en toute sécurité avec un quelconque framework d'automatisation.

Il est fortement recommandé de l'utiliser conjointement avec vmDebugProtection, vmBytecodeArrayEncodingKey et vmBytecodeArrayEncodingKeyGetter.

vmDefenseHook

Type: { name: string, aliases?: object } Default: ''

vmDefenseHook prend un objet à deux clés : name (obligatoire) et aliases (facultatif).

name est une fonction globale définie par votre page hôte qu'une défense de la VM (vmDebugProtection / vmSelfDefending) appelle avec un objet signal lorsqu'elle détecte un signal hostile — un débogueur ou un inspecteur, un navigateur headless / d'automatisation, un processus d'agent de codage IA, un domaine non autorisé, etc. Utilisez-la pour remonter l'événement vers votre backend (par exemple via navigator.sendBeacon). Le hook est un simple puits de télémétrie : sa valeur de retour est ignorée, et un hook absent ou qui lève une exception est un no-op silencieux qui ne peut jamais désactiver une défense. Pour changer ce que fait une défense lors d'une détection, utilisez vmDefenseReaction.

aliases renomme facultativement les champs de cet objet signal — abordé plus bas dans Renommer les champs du signal.

L'objet signal. Le hook reçoit un unique signal :

  • source — le détecteur précis qui s'est déclenché (voir le tableau).
  • category — le groupe sous lequel il remonte : automation (navigateurs non humains), debugger (un débogueur/inspecteur est actif), sandbox (hôte instrumenté/factice), domain (violation du verrouillage par domaine), tamper (fonctions intégrées modifiées à l'exécution) ou integrity (le code propre de la VM a été altéré).
  • score / threshold — l'intensité du déclenchement du détecteur et la valeur qu'il devait atteindre ; le hook ne se déclenche qu'une fois score >= threshold. La plupart des contrôles sont tout ou rien (un unique signal décisif) ; headless additionne plusieurs signaux liés à la forme du navigateur, si bien que son score est généralement supérieur à son threshold.
sourcedétectecategory
integrityle code VM obfusqué lui-même a été modifiéintegrity
nodedu code destiné au navigateur s'exécutant sous Node.jsdebugger
debuggerune session de débogueur ou d'inspecteur attachée ou active, ou un environnement de débogagedebugger
headlessun navigateur headless est utilisé pour exécuter le codeautomation
agentun agent de codage IA exécutant le codeautomation
timingune pause d'exécution suggérant un point d'arrêt ou un débogueur en pas à pasdebugger
sandboxle code s'exécute dans un bac à sable ou un environnement hôte facticesandbox
domainl'origine de la page n'est pas dans la liste d'autorisation vmDomainLockdomain
nativeHookune fonction native intégrée a été remplacée ou hookéetamper

Enregistrement du hook. Définissez-le comme une simple globale avant le chargement du bundle obfusqué — le runtime de la VM et ses défenses s'exécutent avant votre programme (protégé), de sorte que de nombreuses détections se produisent au démarrage :

// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }

Un hook défini à l'intérieur du source obfusqué est enregistré trop tard pour intercepter les détections du démarrage et, s'il est compilé par la VM, il reste inaccessible tant que votre programme n'a pas démarré. Il reste sans danger dans tous les cas (un hook absent est un no-op, et un garde-fou anti-réentrance empêche tout emballement), mais pour une couverture complète, enregistrez-le en amont. Pour tout de même protéger votre logique de remontée, gardez comme hook enregistré un tampon d'une ligne ((window.__vmDet = window.__vmDet || []).push(signal)) et lisez/envoyez ce tampon depuis votre code obfusqué.

Renommer les champs du signal (aliases). Les valeurs source/category par défaut sont des noms descriptifs : quiconque instrumente le callback (ou lit la sortie) peut donc reconnaître la protection et le détecteur qui s'est déclenché. aliases remplace les noms des champs du signal par des jetons opaques de votre choix, appliqués à l'intérieur de la VM avant l'émission du signal, de sorte que ces noms n'apparaissent jamais dans la sortie ni ne parviennent au callback. Votre application connaît sa propre correspondance et transmet les jetons à votre backend.

Les alias se définissent champ par champ, en séparant le renommage des clés de celui des valeurs : chaque champ accepte une key (le nom de propriété que reçoit le callback) ; les champs de type chaîne source et category acceptent en plus une table values, tandis que score / threshold sont des nombres et n'acceptent qu'une key. Les noms que vous pouvez mapper (tout autre est rejeté au moment du build) :

  • clés de champsource, category, score, threshold
  • valeurs de sourceheadless, agent, node, debugger, timing, sandbox, domain, nativeHook, integrity
  • valeurs de categoryautomation, debugger, sandbox, domain, tamper, integrity
vmDefenseHook: {
    name: '__vmDetection',
    aliases: {
        source:    { key: 'a8Qm', values: { headless: 'xP4m9Q' } },
        category:  { key: 'p3Tx', values: { automation: 'bQ7s1M' } },
        score:     { key: 's1' },
        threshold: { key: 't1' }
    }
    // the callback now receives e.g. { a8Qm: 'xP4m9Q', p3Tx: 'bQ7s1M', s1: <score>, t1: <threshold> }
}

Il s'agit d'une gêne à l'identification, pas d'un secret — la correspondance peut toujours être déduite par tâtonnements répétés — de sorte que son seul bénéfice est de ne pas exposer des noms stables et explicites. Les entrées non renseignées conservent leur nom par défaut.

Une chaîne simple (vmDefenseHook: '__vmDetection') est acceptée comme raccourci de { name: '__vmDetection' } mais est dépréciée — préférez la forme objet.

vmDefenseReaction

Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }

Configure la façon dont chaque catégorie de détection réagit. Elle n'active rien — les défenses elles-mêmes sont activées par vmSelfDefending, vmDebugProtection et vmDomainLock ; cette option ne fait que choisir comment réagit une défense déjà activée. La catégorie est l'unité de contrôle — chaque détecteur d'une catégorie applique la réaction de cette catégorie.

Chaque catégorie regroupe les détecteurs qui surveillent un même type de condition hostile. Une catégorie ne réagit que lorsque l'option qui émet ses détecteurs est activée :

CatégorieActivée parRéagit lorsque
automationvmSelfDefending ou vmDebugProtectionLe code est piloté par un logiciel et non par une personne : navigateur headless ou automatisé, framework de scraping ou de test, ou agent de codage IA parcourant la page pas à pas.
debuggervmDebugProtection ou vmSelfDefendingQuelqu'un a ouvert un débogueur ou l'inspecteur des outils de développement du navigateur et parcourt le code en cours d'exécution pour le comprendre.
sandboxvmDebugProtectionLe code ne s'exécute pas du tout dans un vrai navigateur — il a été transposé dans un environnement JavaScript émulé ou scripté afin d'être exécuté et étudié hors ligne.
domainvmDomainLockLe code s'exécute sur un site que vous n'avez pas autorisé : un hôte absent de votre liste d'autorisation vmDomainLock (par exemple votre bundle copié sur le domaine d'un tiers).
tampervmSelfDefendingL'environnement JavaScript autour de la VM a été modifié pour l'observer ou la détourner, par exemple en remplaçant des fonctions natives du navigateur par des versions instrumentées.
integrityvmSelfDefendingLe code du bundle protégé lui-même a été modifié ou patché depuis que vous l'avez généré.

Chaque catégorie correspond à une ou plusieurs des options vmSelfDefending, vmDebugProtection et vmDomainLock ; il n'existe aucune catégorie en dehors de ces trois options, et une réaction définie pour une catégorie dont l'option est désactivée n'a tout simplement aucun effet.

Les clés sont ces six noms de catégories, ou default (valeur de repli pour les catégories non spécifiées). Les valeurs sont :

  • break — rompre immédiatement
  • decoy — continuer à s'exécuter sur un état empoisonné, en produisant silencieusement des résultats erronés
  • none — ne rien faire localement (télémétrie uniquement)

Les valeurs par défaut par catégorie sont indiquées ci-dessus ; une catégorie que vous ne définissez pas (ou que vous laissez à sa valeur par défaut) utilise cette valeur par défaut. default atteint toutes les catégories, y compris celles qui sont correctes par construction (integrity, tamper) ; { default: 'none' } produit donc un build véritablement non intrusif, purement télémétrique :

vmDefenseReaction: { default: 'none' }              // never break — pair with vmDefenseHook
vmDefenseReaction: { automation: 'none', domain: 'break' }   // tolerate automation FPs, still break on a bad domain

vmStatefulOpcodes

Type: boolean Default: false

Fait dépendre la signification des opcodes de leur position dans le bytecode. Chaque position possède une correspondance opcode-vers-gestionnaire différente, dérivée d'une graine, de sorte qu'un même numéro d'opcode effectue des opérations différentes selon la position.

vmCallContextOpcodes

Type: boolean Default: false

Fait dépendre une fonction protégée de l'endroit d'où elle est appelée, de sorte qu'elle ne peut pas être extraite du code puis exécutée ou analysée isolément — elle ne se comporte correctement que lorsqu'elle est invoquée via ses véritables sites d'appel dans le programme. Cette option affecte les performances à l'exécution.

Actuellement, seules les constructions suivantes sont prises en charge :

  • les déclarations de fonction (function f() {}) ;
  • les expressions de fonction et les fonctions fléchées affectées à une variable (const f = () => {}) ;
  • les méthodes privées d'instance (this.#m()).

Dans tous les cas, la fonction doit toujours être atteinte par un appel direct (f(), this.#m()). Si elle est stockée dans une autre variable, passée en argument ou utilisée d'une autre manière comme valeur, elle reste non protégée. Les fonctions asynchrones sont prises en charge ; les générateurs ne le sont pas.

Cette option est expérimentale et peut casser votre code ; testez donc soigneusement la sortie avant de l'utiliser.

vmStackEncoding

Type: boolean Default: false

Chiffre les valeurs présentes sur la pile de la VM pendant l'exécution. Les valeurs sont encodées lorsqu'elles sont empilées et décodées lorsqu'elles sont dépilées, de sorte qu'une inspection de la mémoire montre des données chiffrées au lieu des valeurs réelles.

Cette option affecte fortement les performances.

vmCompactDispatcher

Type: boolean Default: false

Utilise un seul exécuteur VM au lieu de deux exécuteurs (synchrone + générateur). Réduit la taille du code obfusqué mais ajoute une surcharge d'environ 20 % sur un code fortement récursif.

  • false (par défaut) : deux exécuteurs — performances optimales, sortie plus volumineuse
  • true : un seul exécuteur — sortie plus petite, légèrement plus lente

vmStringArrayBytecodeOnly

Type: boolean Default: false

Lorsqu'elle est activée, le tableau de chaînes n'extrait que les chaînes issues des données de bytecode — aucune autre chaîne du code n'est transformée. Cela active de force stringArray même s'il n'est pas explicitement défini.

Pourquoi l'utiliser : extraire toutes les chaînes du runtime de la VM vers un tableau de chaînes est lent. Cette option ne cible que le contenu du bytecode pour l'extraction dans le tableau de chaînes, améliorant les performances tout en protégeant les constantes du bytecode.

  • Lorsque vmBytecodeArrayEncoding: false — les chaînes présentes dans les pools de constantes du bytecode (tableaux c) sont extraites
  • Lorsque vmBytecodeArrayEncoding: true — les chaînes de bytecode encodées en base64 au niveau supérieur sont extraites
  • stringArrayThreshold continue de contrôler le pourcentage de ces chaînes de bytecode qui sont extraites

vmDomainLock

Type: string[] Default: []

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Restreint le code obfusqué à des domaines et/ou sous-domaines précis, et est bien plus difficile à localiser et à retirer que domainLock.

Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à vmDomainLockRedirectUrl, et les appels protégés ultérieurs renverront des résultats incorrects même si la redirection est supprimée.

Domaines et sous-domaines multiples

Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.

vmDomainLockRedirectUrl

Type: string Default: about:blank

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par vmDomainLock.

Options de préréglage

Obfuscation élevée, performances faibles

Les performances seront bien plus lentes que sans obfuscation

{
    compact: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 1,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 1,
    debugProtection: true,
    debugProtectionInterval: 4000,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: true,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: true,
    splitStringsChunkLength: 5,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: true,
    stringArrayEncoding: ['rc4'],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 5,
    stringArrayWrappersChainedCalls: true,    
    stringArrayWrappersParametersMaxCount: 5,
    stringArrayWrappersType: 'function',
    stringArrayThreshold: 1,
    transformObjectKeys: true
}

Obfuscation moyenne, performances optimales

Les performances seront plus lentes que sans obfuscation

{
    compact: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 0.75,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 0.4,
    debugProtection: false,
    debugProtectionInterval: 0,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: true,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: true,
    splitStringsChunkLength: 10,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: true,
    stringArrayCallsTransformThreshold: 0.75,
    stringArrayEncoding: ['base64'],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 2,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 4,
    stringArrayWrappersType: 'function',
    stringArrayThreshold: 0.75,
    transformObjectKeys: true
}

Obfuscation faible, performances élevées

Les performances resteront à un niveau relativement normal

{
    compact: true,
    controlFlowFlattening: false,
    deadCodeInjection: false,
    debugProtection: false,
    debugProtectionInterval: 0,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: false,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: false,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: false,
    stringArrayEncoding: [],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 1,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 2,
    stringArrayWrappersType: 'variable',
    stringArrayThreshold: 0.75
}

Préréglage par défaut, performances élevées

{
    compact: true,
    controlFlowFlattening: false,
    deadCodeInjection: false,
    debugProtection: false,
    debugProtectionInterval: 0,
    disableConsoleOutput: false,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: false,
    renameGlobals: false,
    selfDefending: false,
    simplify: true,
    splitStrings: false,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: false,
    stringArrayCallsTransformThreshold: 0.5,
    stringArrayEncoding: [],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 1,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 2,
    stringArrayWrappersType: 'variable',
    stringArrayThreshold: 0.75
}

Obfuscation VM Ultra High (sécurité maximale)

Ce préréglage active l'obfuscation en bytecode basée sur une VM avec toutes les fonctionnalités de durcissement, y compris la répartition indirecte. Offre la protection la plus forte, mais avec une taille de sortie plus importante et une exécution bien plus lente.

{
    optionsPreset: 'vm-ultra-high-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,

    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,

    vmBytecodeEncoding: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: true,
    vmMacroOps: true,
    vmDebugProtection: true,
    vmSelfDefending: true,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: true,
    vmCallContextOpcodes: false,
    vmStackEncoding: true,
    vmCompactDispatcher: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 0.5,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 0.5,
    debugProtection: true,
    debugProtectionInterval: 4000,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: true,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: true,
    splitStringsChunkLength: 5,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: true,
    stringArrayEncoding: ['rc4'],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 5,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 5,
    stringArrayWrappersType: 'function',
    stringArrayThreshold: 0.5,
    transformObjectKeys: true
}

VM Anti-LLM (protection contre les agents IA)

Ce préréglage est spécifiquement conçu pour empêcher les agents IA et les LLM de rétro-concevoir du code en bytecode VM. Basé sur vm-default, avec l'auto-défense et la protection anti-débogage activées. Plus léger que vm-high-obfuscation, mais spécifiquement durci contre l'analyse automatisée.

{
    optionsPreset: 'vm-anti-llm'
}

Inclut :

  • l'obfuscation en bytecode VM avec tableau de chaînes (depuis vm-default)
  • vmSelfDefending — détection anti-hook, hash d'intégrité, empreinte de source, vérification d'un realm propre via iframe, dérivation de clé par chiffrement ARX
  • vmDebugProtection — contrôles anti-débogage dans la boucle de répartition de la VM
  • debugProtection: false — pas de protection anti-débogage héritée (la protection anti-débogage de la VM est supérieure)

Obfuscation VM High (sécurité la plus élevée)

Ce préréglage active l'obfuscation en bytecode basée sur une VM avec la plupart des fonctionnalités de durcissement. Offre une protection forte avec de meilleures performances que le préréglage ultra-high.

{
    optionsPreset: 'vm-high-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,
    vmBytecodeEncoding: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: true,
    vmMacroOps: true,
    vmDebugProtection: true,
    vmSelfDefending: true,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: true,
    vmCallContextOpcodes: false,
    vmStackEncoding: true,
    vmCompactDispatcher: false
}

Obfuscation VM Medium (sécurité équilibrée)

Ce préréglage active l'obfuscation en bytecode basée sur une VM avec un ensemble équilibré de fonctionnalités de durcissement. Bon compromis entre sécurité et performances.

{
    optionsPreset: 'vm-medium-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,
    vmBytecodeEncoding: true,
    vmBytecodeArrayEncoding: false,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: true,
    vmMacroOps: true,
    vmDebugProtection: true,
    vmSelfDefending: false,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: false,
    vmCallContextOpcodes: false,
    vmStackEncoding: false,
    vmCompactDispatcher: false
}

Obfuscation VM Low (sécurité de base, meilleures performances)

Ce préréglage active une obfuscation en bytecode VM de base, sans fonctionnalités de durcissement supplémentaires. Bon équilibre entre sécurité et taille de sortie.

{
    optionsPreset: 'vm-low-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: false,
    vmBytecodeEncoding: false,
    vmBytecodeArrayEncoding: false,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: false,
    vmMacroOps: false,
    vmDebugProtection: false,
    vmSelfDefending: false,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: false,
    vmCallContextOpcodes: false,
    vmStackEncoding: false,
    vmCompactDispatcher: false
}

VM Default (VM + protection du tableau de chaînes)

Ce préréglage combine une obfuscation en bytecode VM de base avec la protection par tableau de chaînes. Bon point de départ pour l'obfuscation VM avec protection des chaînes.

{
    optionsPreset: 'vm-default'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,
    vmBytecodeEncoding: false,
    vmBytecodeArrayEncoding: true,
    vmStringArrayBytecodeOnly: true,
    vmAsyncExecutor: false,
    vmJumpsEncoding: false,
    vmMacroOps: false,
    vmDebugProtection: false,
    vmSelfDefending: false,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: false,
    vmCallContextOpcodes: false,
    vmStackEncoding: false,
    vmCompactDispatcher: false,
    stringArray: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayThreshold: 1,
    stringArrayIndexShift: true,
    stringArrayIndexesType: ['hexadecimal-number'],
    stringArrayCallsTransform: true,
    stringArrayCallsTransformThreshold: 1,
    stringArrayWrappersCount: 3,
    stringArrayWrappersType: 'function',
    stringArrayWrappersParametersMaxCount: 5,
    stringArrayWrappersChainedCalls: true,
    stringArrayEncoding: ['base64'],
    splitStrings: true,
    splitStringsChunkLength: 6
}

compact

Type: boolean Default: true

Sortie de code compacte sur une seule ligne.

config

Type: string Default: ``

Nom du fichier de configuration JS/JSON contenant les options de l'obfuscateur. Ces options seront remplacées par celles passées directement en ligne de commande (CLI).

controlFlowFlattening

Type: boolean Default: false

⚠️ Cette option affecte fortement les performances, jusqu'à une exécution 1,5x plus lente. Utilisez controlFlowFlatteningThreshold pour définir le pourcentage de nœuds concernés par l'aplatissement du flux de contrôle.

Active l'aplatissement du flux de contrôle du code. L'aplatissement du flux de contrôle est une transformation de la structure du code source qui en complique la compréhension.

Exemple :

// input
(function(){
    function foo () {
        return function () {
            var sum = 1 + 2;
            console.log(1);
            console.log(2);
            console.log(3);
            console.log(4);
            console.log(5);
            console.log(6);
        }
    }
    
    foo()();
})();

// output
(function () {
    function _0x3bfc5c() {
        return function () {
            var _0x3260a5 = {
                'WtABe': '4|0|6|5|3|2|1',
                'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {
                    return _0x427a8e + _0x43354c;
                }
            };
            var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;
            while (!![]) {
                switch (_0x1ad4d6[_0x1a7b12++]) {
                case '0':
                    console['log'](0x1);
                    continue;
                case '1':
                    console['log'](0x6);
                    continue;
                case '2':
                    console['log'](0x5);
                    continue;
                case '3':
                    console['log'](0x4);
                    continue;
                case '4':
                    var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);
                    continue;
                case '5':
                    console['log'](0x3);
                    continue;
                case '6':
                    console['log'](0x2);
                    continue;
                }
                break;
            }
        };
    }

	_0x3bfc5c()();
}());

controlFlowFlatteningThreshold

Type: number Default: 0.75 Min: 0 Max: 1

Probabilité que la transformation controlFlowFlattening soit appliquée à un nœud donné.

Ce paramètre est particulièrement utile pour les codes volumineux, car un grand nombre de transformations du flux de contrôle peut ralentir votre code et en augmenter la taille.

controlFlowFlatteningThreshold: 0 équivaut à controlFlowFlattening: false.

deadCodeInjection

Type: boolean Default: false

⚠️ Augmente considérablement la taille du code obfusqué (jusqu'à 200 %) ; à n'utiliser que si la taille du code obfusqué n'a pas d'importance. Utilisez deadCodeInjectionThreshold pour définir le pourcentage de nœuds concernés par l'injection de code mort.
⚠️ Cette option active de force l'option stringArray.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé.

Avec cette option, des blocs aléatoires de code mort sont ajoutés au code obfusqué.

Exemple :

// input
(function(){
    if (true) {
        var foo = function () {
            console.log('abc');
        };
        var bar = function () {
            console.log('def');
        };
        var baz = function () {
            console.log('ghi');
        };
        var bark = function () {
            console.log('jkl');
        };
        var hawk = function () {
            console.log('mno');
        };

        foo();
        bar();
        baz();
        bark();
        hawk();
    }
})();

// output
var _0x37b8 = [
    'YBCtz',
    'GlrkA',
    'urPbb',
    'abc',
    'NMIhC',
    'yZgAj',
    'zrAId',
    'EtyJA',
    'log',
    'mno',
    'jkl',
    'def',
    'Quzya',
    'IWbBa',
    'ghi'
];
function _0x43a7(_0x12cf56, _0x587376) {
    _0x43a7 = function (_0x2f87a8, _0x47eac2) {
        _0x2f87a8 = _0x2f87a8 - (0x16a7 * 0x1 + 0x5 * 0x151 + -0x1c92);
        var _0x341e03 = _0x37b8[_0x2f87a8];
        return _0x341e03;
    };
    return _0x43a7(_0x12cf56, _0x587376);
}
(function () {
    if (!![]) {
        var _0xbbe28f = function () {
            var _0x2fc85f = _0x43a7;
            if (_0x2fc85f(0xaf) === _0x2fc85f(0xae)) {
                _0x1dd94f[_0x2fc85f(0xb2)](_0x2fc85f(0xb5));
            } else {
                console[_0x2fc85f(0xb2)](_0x2fc85f(0xad));
            }
        };
        var _0x5e46bc = function () {
            var _0x15b472 = _0x43a7;
            if (_0x15b472(0xb6) !== _0x15b472(0xaa)) {
                console[_0x15b472(0xb2)](_0x15b472(0xb5));
            } else {
                _0x47eac2[_0x15b472(0xb2)](_0x15b472(0xad));
            }
        };
        var _0x3669e8 = function () {
            var _0x47a442 = _0x43a7;
            if (_0x47a442(0xb7) !== _0x47a442(0xb0)) {
                console[_0x47a442(0xb2)](_0x47a442(0xb8));
            } else {
                _0x24e0bf[_0x47a442(0xb2)](_0x47a442(0xb3));
            }
        };
        var _0x28b05a = function () {
            var _0x497902 = _0x43a7;
            if (_0x497902(0xb1) === _0x497902(0xb1)) {
                console[_0x497902(0xb2)](_0x497902(0xb4));
            } else {
                _0x59c9c6[_0x497902(0xb2)](_0x497902(0xb4));
            }
        };
        var _0x402a54 = function () {
            var _0x1906b7 = _0x43a7;
            if (_0x1906b7(0xab) === _0x1906b7(0xac)) {
                _0xb89cd0[_0x1906b7(0xb2)](_0x1906b7(0xb8));
            } else {
                console[_0x1906b7(0xb2)](_0x1906b7(0xb3));
            }
        };
        _0xbbe28f();
        _0x5e46bc();
        _0x3669e8();
        _0x28b05a();
        _0x402a54();
    }
}());

deadCodeInjectionThreshold

Type: number Default: 0.4 Min: 0 Max: 1

Permet de définir le pourcentage de nœuds concernés par deadCodeInjection.

debugProtection

Type: boolean Default: false

⚠️ Peut figer votre navigateur si vous ouvrez les outils de développement.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.

Cette option rend presque impossible l'utilisation de la fonction debugger des outils de développement (aussi bien sur les navigateurs basés sur WebKit que sur Mozilla Firefox).

debugProtectionInterval

Type: number Default: 0

⚠️ Peut figer votre navigateur ! À utiliser à vos risques et périls.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.

Si cette option est définie, un intervalle en millisecondes est utilisé pour forcer le mode débogage sur l'onglet Console, rendant plus difficile l'utilisation des autres fonctionnalités des outils de développement. Fonctionne si debugProtection est activé. La valeur recommandée est comprise entre 2000 et 4000 millisecondes.

disableConsoleOutput

Type: boolean Default: false

⚠️ Cette option désactive les appels à console de façon globale pour tous les scripts

Désactive l'utilisation de console.log, console.info, console.error, console.warn, console.debug, console.exception et console.trace en les remplaçant par des fonctions vides. Cela rend l'utilisation du débogueur plus difficile.

domainLock

Type: string[] Default: []

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Permet d'exécuter le code source obfusqué uniquement sur des domaines et/ou sous-domaines précis. Cela rend très difficile le simple copier-coller de votre code source pour l'exécuter ailleurs.

Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à l'option domainLockRedirectUrl.

Domaines et sous-domaines multiples

Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.

domainLockRedirectUrl

Type: string Default: about:blank

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par domainLock

exclude

Type: string[] Default: []

Noms de fichiers ou motifs glob indiquant les fichiers à exclure de l'obfuscation.

forceTransformStrings

Type: string[] Default: []

Force la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis.

⚠️ Cette option n'affecte que les chaînes qui ne devraient pas être transformées par stringArrayThreshold (ou d'éventuels autres seuils à l'avenir)

Cette option a priorité sur l'option reservedStrings, mais pas sur les conditional comments.

Exemple :

	{
		forceTransformStrings: [
			'some-important-value',
			'some-string_\d'
		]
	}

identifierNamesCache

Type: Object | null Default: null

L'objectif principal de cette option est de pouvoir réutiliser les mêmes noms d'identifiants lors de l'obfuscation de plusieurs sources/fichiers.

Actuellement, deux types d'identifiants sont pris en charge :

  • Identifiants globaux :
    • Tous les identifiants globaux sont écrits dans le cache ;
    • Tous les identifiants globaux non déclarés correspondants sont remplacés par les valeurs du cache.
  • Identifiants de propriété, uniquement lorsque l'option renameProperties est activée :
    • Tous les identifiants de propriété sont écrits dans le cache ;
    • Tous les identifiants de propriété correspondants sont remplacés par les valeurs du cache.

API Node.js

Si la valeur null est passée, le cache est entièrement désactivé.

Si un objet vide ({}) est passé, l'écriture des noms d'identifiants dans l'objet-cache (type TIdentifierNamesCache) est activée. Cet objet-cache est accessible via l'appel de la méthode getIdentifierNamesCache de l'objet ObfuscationResult.

L'objet-cache obtenu peut ensuite être utilisé comme valeur de l'option identifierNamesGenerator afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des sources suivantes.

Exemple :

const source1ObfuscationResult = JavaScriptObfuscator.obfuscate(
    `
        function foo(arg) {
           console.log(arg)
        }
        
        function bar() {
            var bark = 2;
        }
    `,
    {
        compact: false,
        identifierNamesCache: {},
        renameGlobals: true
    }
)

console.log(source1ObfuscationResult.getIdentifierNamesCache());
/*
    { 
        globalIdentifiers: {
            foo: '_0x5de86d',
            bar: '_0x2a943b'
        }
    }
*/



const source2ObfuscationResult = JavaScriptObfuscator.obfuscate(
    `
        // Expecting that these global functions are defined in another obfuscated file
        foo(1);
        bar();
        
        // Expecting that this global function is defined in third-party package
        baz();
    `,
    {
        compact: false,
        identifierNamesCache: source1ObfuscationResult.getIdentifierNamesCache(),
        renameGlobals: true
    }
)

console.log(source2ObfuscationResult.getObfuscatedCode());
/*
    _0x5de86d(0x1);
    _0x2a943b();
    baz();
 */

CLI

La CLI dispose d'une option différente, --identifier-names-cache-path, qui permet de définir le chemin d'un fichier .json existant servant à lire et écrire le cache des noms d'identifiants.

Si le chemin d'un fichier vide est passé, le cache des noms d'identifiants y sera écrit.

Ce fichier contenant un cache existant peut être réutilisé comme valeur de l'option --identifier-names-cache-path afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des fichiers suivants.

identifierNamesGenerator

Type: string Default: hexadecimal

Définit le générateur de noms d'identifiants.

Valeurs disponibles :

  • dictionary : noms d'identifiants issus de la liste identifiersDictionary
  • hexadecimal : noms d'identifiants du type _0xabc123
  • mangled : noms d'identifiants courts comme a, b, c
  • mangled-shuffled : identique à mangled, mais avec un alphabet mélangé

identifiersDictionary

Type: string[] Default: []

Définit le dictionnaire d'identifiants pour l'option identifierNamesGenerator : dictionary. Chaque identifiant du dictionnaire sera utilisé en plusieurs variantes, avec une casse différente pour chaque caractère. Le nombre d'identifiants du dictionnaire doit donc dépendre du nombre d'identifiants présents dans le code source d'origine.

identifiersPrefix

Type: string Default: ''

Définit un préfixe pour tous les identifiants globaux.

Utilisez cette option lorsque vous obfusquez plusieurs fichiers. Elle permet d'éviter les conflits entre les identifiants globaux de ces fichiers. Le préfixe doit être différent pour chaque fichier.

randomIdentifiersPrefix

Type: boolean Default: false

Ajoute un préfixe aléatoire dérivé de la graine (6 caractères alphanumériques) à tous les identifiants globaux. Utilisez cette option pour éviter les collisions entre des bundles obfusqués séparément et chargés dans la même portée globale — elle évite d'avoir à choisir manuellement un identifiersPrefix unique pour chaque bundle.

  • La valeur aléatoire est dérivée de l'option seed et du hash du code source ; des builds reproductibles avec la même graine produisent donc le même préfixe.
  • Combinée à identifiersPrefix, les caractères aléatoires sont ajoutés à la suite du préfixe fourni par l'utilisateur (par exemple myApp + aBc123 aléatoire → myAppaBc123).
  • Combinée à vmObfuscation, la valeur aléatoire remplace le préfixe vm par défaut — le caractère aléatoire garantit déjà l'unicité.

ignoreImports

Type: boolean Default: false

Empêche l'obfuscation des imports require. Peut être utile dans certains cas où, pour une raison ou une autre, l'environnement d'exécution exige que ces imports utilisent uniquement des chaînes statiques.

inputFileName

Type: string Default: ''

Permet de définir le nom du fichier d'entrée contenant le code source. Ce nom est utilisé en interne pour la génération de la source map. Requis lors de l'utilisation de l'API NodeJS lorsque l'option sourceMapSourcesMode a la valeur sources.

log

Type: boolean Default: false

Active la journalisation des informations dans la console.

numbersToExpressions

Type: boolean Default: false

Active la conversion des nombres en expressions.

Exemple :

// input
const foo = 1234;

// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;

optionsPreset

Type: string Default: default

Permet de définir un préréglage d'options.

Valeurs disponibles :

  • vm-default ;
  • vm-low-obfuscation ;
  • vm-medium-obfuscation ;
  • vm-high-obfuscation ;
  • vm-ultra-high-obfuscation ;
  • vm-anti-llm ;
  • default ;
  • low-obfuscation ;
  • medium-obfuscation ;
  • high-obfuscation.

Toutes les options supplémentaires seront fusionnées avec le préréglage d'options sélectionné.

parseHtml

Type: boolean Default: false

Active l'obfuscation du JavaScript contenu dans les balises HTML <script>.

Lorsqu'elle est activée, l'obfuscateur :

  • Détecte automatiquement si l'entrée est du HTML (en recherchant les balises <!DOCTYPE, <html>, <head>, <body> ou <script>)
  • Extrait le JavaScript des balises <script> marquées par l'attribut data-javascript-obfuscator
  • Obfusque chaque script marqué individuellement tout en préservant la structure HTML
  • Réinjecte le code obfusqué à ses positions d'origine

Important : seuls les scripts portant l'attribut data-javascript-obfuscator sont obfusqués. Chaque script marqué est obfusqué de façon individuelle et indépendante. Cela signifie que :

  • Le code contenu dans les balises de script marquées doit être isolé : il ne doit PAS référencer de variables, fonctions ou classes définies dans d'autres balises de script marquées
  • Les scripts non marqués peuvent tout de même accéder aux globales définies par les scripts marqués (via des déclarations var ou des affectations explicites à globalThis)
  • Cela vous donne un contrôle explicite sur les scripts à protéger

Obfusqués (doivent porter l'attribut data-javascript-obfuscator) :

  • <script data-javascript-obfuscator> - scripts ordinaires
  • <script type="text/javascript" data-javascript-obfuscator> - scripts au type explicite
  • Scripts comportant des attributs supplémentaires (id, class, autres data-*, etc.)

Ignorés (laissés inchangés) :

  • Scripts sans l'attribut data-javascript-obfuscator
  • <script type="module"> - modules ES (même avec l'attribut)
  • <script src="..."> - scripts externes (même avec l'attribut)
  • Balises de script vides

Remarque : aucune source map n'est générée lorsque parseHtml est activé, car elle ne correspondrait pas correctement à la sortie HTML.

Exemple :

// input
const html = `<!DOCTYPE html>
<html>
<body>
<!-- This script will NOT be obfuscated -->
<script>
var helper = 'utility';
</script>

<!-- This script WILL be obfuscated -->
<script data-javascript-obfuscator>
var greeting = 'Hello World';
console.log(greeting);
</script>
</body>
</html>`;

JavaScriptObfuscator.obfuscate(html, {
    parseHtml: true,
    stringArray: true
});

// output: HTML with only the marked script obfuscated

renameGlobals

Type: boolean Default: false

⚠️ cette option peut casser votre code. Ne l'activez que si vous savez ce qu'elle fait !

Active l'obfuscation des noms de variables et de fonctions globales avec déclaration.

Lorsque cette option est désactivée et que le code d'entrée déclare des fonctions ou des classes dans la portée globale (c'est-à-dire que le code n'est pas encapsulé dans une IIFE), leurs noms sont conservés tels quels dans la sortie obfusquée — d'autres scripts peuvent y faire référence par leur nom. Sous vmObfuscation, un avertissement VMGlobalFunctionNamesNotRenamed listant ces noms est signalé, car le corps de la fonction est masqué sous forme de bytecode tandis que le nom lisible de premier niveau révèle toujours ce que fait le code (par exemple à un LLM). Pour éviter cette exposition, encapsulez le code dans une IIFE ou activez cette option.

renameProperties

Type: boolean Default: false

⚠️ cette option PEUT casser votre code. Ne l'activez que si vous savez ce qu'elle fait !

Active le renommage des noms de propriétés. Toutes les propriétés DOM intégrées ainsi que les propriétés des classes JavaScript de base sont ignorées.

Pour basculer entre les modes safe et unsafe de cette option, utilisez l'option renamePropertiesMode.

Pour définir le format des noms de propriétés renommés, utilisez l'option identifierNamesGenerator.

Pour contrôler quelles propriétés seront renommées, utilisez l'option reservedNames.

Exemple :

// input
(function () {
    const foo = {
        prop1: 1,
        prop2: 2,
        calc: function () {
            return this.prop1 + this.prop2;
        }
    };
    
    console.log(foo.calc());
})();

// output
(function () {
    const _0x46529b = {
        '_0x10cec7': 0x1,
        '_0xc1c0ca': 0x2,
        '_0x4b961d': function () {
            return this['_0x10cec7'] + this['_0xc1c0ca'];
        }
    };
    console['log'](_0x46529b['_0x4b961d']());
}());

renamePropertiesMode

Type: string Default: safe

⚠️ Même en mode safe, l'option renameProperties PEUT casser votre code.

Spécifie le mode de l'option renameProperties :

  • safe - comportement par défaut depuis la version 2.11.0. Tente de renommer les propriétés de façon plus sûre afin d'éviter les erreurs d'exécution. Dans ce mode, certaines propriétés sont exclues du renommage.
  • unsafe - comportement par défaut avant la version 2.11.0. Renomme les propriétés de façon non sécurisée, sans aucune restriction.

Si un fichier utilise des propriétés d'un autre fichier, utilisez l'option identifierNamesCache pour conserver les mêmes noms de propriétés entre ces fichiers.

reservedNames

Type: string[] Default: []

Désactive l'obfuscation et la génération des identifiants correspondant aux motifs RegExp fournis.

Exemple :

	{
		reservedNames: [
			'^someVariable',
			'functionParameter_\d'
		]
	}

reservedStrings

Type: string[] Default: []

Désactive la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis. Les chaînes correspondantes resteront visibles dans la sortie obfusquée.

Avec l'obfuscation VM, les chaînes réservées sont stockées dans un tableau distinct non chiffré afin de rester visibles. C'est utile pour les chaînes qui doivent rester lisibles, comme les points de terminaison d'API pour la supervision ou les identifiants de bibliothèques.

Exemple :

	{
		reservedStrings: [
			'react-native',
			'\.\/src\/test',
			'some-string_\d'
		]
	}

seed

Type: string|number Default: 0

Cette option définit la graine du générateur aléatoire. C'est utile pour obtenir des résultats reproductibles.

Si la graine vaut 0, le générateur aléatoire fonctionne sans graine.

selfDefending

Type: boolean Default: false

⚠️ Ne modifiez d'aucune façon le code obfusqué après l'obfuscation avec cette option, car toute modification comme une minification du code peut déclencher l'auto-défense et le code cessera de fonctionner !
⚠️ Cette option force la valeur compact à true
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmSelfDefending.

Cette option rend le code de sortie résistant à la mise en forme et au renommage des variables. Si l'on tente d'utiliser un embellisseur JavaScript sur le code obfusqué, celui-ci cessera de fonctionner, ce qui le rend plus difficile à comprendre et à modifier.

simplify

Type: boolean Default: true

Active une obfuscation supplémentaire du code par simplification.

⚠️ dans les prochaines versions, l'obfuscation des littéraux boolean (true => !![]) sera déplacée sous cette option.

Exemple :

// input
if (condition1) {
    const foo = 1;
    const bar = 2;
  
    console.log(foo);
  
    return bar;
} else if (condition2) {
    console.log(1);
    console.log(2);
    console.log(3);
  
    return 4;
} else {
    return 5;
}

// output
if (condition1) {
    const foo = 0x1, bar = 0x2;
    return console['log'](foo), bar;
} else
    return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;

sourceMap

Type: boolean Default: false

Active la génération d'une source map pour le code obfusqué.

Les source maps peuvent vous aider à déboguer votre code source JavaScript obfusqué. Si vous souhaitez ou devez déboguer en production, vous pouvez téléverser le fichier de source map distinct vers un emplacement secret, puis y diriger votre navigateur.

sourceMapBaseUrl

Type: string Default: ``

Définit l'URL de base de l'URL d'import de la source map lorsque sourceMapMode: 'separate'.

Exemple en CLI :

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'

Résultat :

//# sourceMappingURL=http://localhost:9000/out.js.map

sourceMapFileName

Type: string Default: ``

Définit le nom du fichier de sortie de la source map lorsque sourceMapMode: 'separate'.

Exemple en CLI :

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example

Résultat :

//# sourceMappingURL=http://localhost:9000/example.js.map

sourceMapMode

Type: string Default: separate

Spécifie le mode de génération de la source map :

  • inline - ajoute la source map à la fin de chaque fichier .js ;
  • separate - génère un fichier '.map' correspondant contenant la source map. Si vous exécutez l'obfuscateur via la CLI, un lien vers le fichier de source map est ajouté à la fin du fichier de code obfusqué : //# sourceMappingUrl=file.js.map.

sourceMapSourcesMode

Type: string Default: sources-content

Permet de contrôler les champs sources et sourcesContent de la source map :

  • sources-content - ajoute un champ sources factice et un champ sourcesContent contenant le code source d'origine ;
  • sources - ajoute un champ sources avec une description de source valide, sans ajouter de champ sourcesContent. Avec l'API NodeJS, il est nécessaire de définir l'option inputFileName, qui sera utilisée comme valeur du champ sources.

splitStrings

Type: boolean Default: false

Découpe les chaînes littérales en morceaux dont la longueur correspond à la valeur de l'option splitStringsChunkLength.

Exemple :

// input
(function(){
    var test = 'abcdefg';
})();

// output
(function(){
    var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();

splitStringsChunkLength

Type: number Default: 10

Définit la longueur des morceaux de l'option splitStrings.

stringArray

Type: boolean Default: true

Retire les littéraux de chaîne et les place dans un tableau spécial. Par exemple, la chaîne "Hello World" dans var m = "Hello World"; sera remplacée par quelque chose comme var m = _0x12c456[0x1];

stringArrayCallsTransform

Type: boolean Default: false

⚠️ l'option stringArray doit être activée

Active la transformation des appels au stringArray. Tous les arguments de ces appels peuvent être extraits vers un autre objet selon la valeur de stringArrayCallsTransformThreshold. Cela rend encore plus difficile la détection automatique des appels au tableau de chaînes.

Exemple :

function foo() {
    var k = {
        c: 0x2f2,
        d: '0x396',
        e: '0x397',
        f: '0x39a',
        g: '0x39d',
        h: 0x398,
        l: 0x394,
        m: '0x39b',
        n: '0x39f',
        o: 0x395,
        p: 0x395,
        q: 0x399,
        r: '0x399'
    };
    var c = i(k.d, k.e);
    var d = i(k.f, k.g);
    var e = i(k.h, k.l);
    var f = i(k.m, k.n);
    function i(c, d) {
        return b(c - k.c, d);
    }
    var g = i(k.o, k.p);
    var h = i(k.q, k.r);
}
function j(c, d) {
    var l = { c: 0x14b };
    return b(c - -l.c, d);
}
console[j(-'0xa6', -'0xa6')](foo());
function b(c, d) {
    var e = a();
    b = function (f, g) {
        f = f - 0xa3;
        var h = e[f];
        return h;
    };
    return b(c, d);
}
function a() {
    var m = [
        'string5',
        'string1',
        'log',
        'string3',
        'string6',
        'string2',
        'string4'
    ];
    a = function () {
        return m;
    };
    return a();
}

stringArrayCallsTransformThreshold

Type: number Default: 0.5

⚠️ les options stringArray et stringArrayCallsTransformThreshold doivent être activées

Ce paramètre permet d'ajuster la probabilité (de 0 à 1) que les appels au tableau de chaînes soient transformés.

stringArrayEncoding

Type: string[] Default: []

⚠️ l'option stringArray doit être activée

Cette option peut ralentir votre script.

Encode tous les littéraux de chaîne du stringArray à l'aide de base64 ou rc4 et insère un code spécial servant à les décoder à l'exécution.

Chaque valeur du stringArray sera encodée selon un encodage choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs encodages.

Valeurs disponibles :

  • 'none' (boolean) : n'encode pas la valeur du stringArray
  • 'base64' (string) : encode la valeur du stringArray avec base64
  • 'rc4' (string) : encode la valeur du stringArray avec rc4. Environ 30 à 50 % plus lent que base64, mais rend plus difficile la récupération des valeurs initiales.

Par exemple, avec les valeurs d'option suivantes, certaines valeurs du stringArray ne seront pas encodées, et d'autres seront encodées avec base64 et rc4 :

stringArrayEncoding: [
    'none',
    'base64',
    'rc4'
]

stringArrayIndexesType

Type: string[] Default: ['hexadecimal-number']

⚠️ l'option stringArray doit être activée

Permet de contrôler le type des index d'appel au tableau de chaînes.

Chaque index d'appel au stringArray sera transformé selon un type choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs types.

Valeurs disponibles :

  • 'hexadecimal-number' (default) : transforme les index d'appel au tableau de chaînes en nombres hexadécimaux
  • 'hexadecimal-numeric-string' : transforme les index d'appel au tableau de chaînes en chaînes numériques hexadécimales

Avant la version 2.9.0, javascript-obfuscator transformait tous les index d'appel au tableau de chaînes avec le type hexadecimal-numeric-string. Cela rend la déobfuscation manuelle légèrement plus difficile, mais permet une détection facile de ces appels par les déobfuscateurs automatiques.

Le nouveau type hexadecimal-number vise à rendre plus difficile la détection automatique des motifs d'appel au tableau de chaînes dans le code.

D'autres types seront ajoutés à l'avenir.

stringArrayIndexShift

Type: boolean Default: true

⚠️ l'option stringArray doit être activée

Active un décalage d'index supplémentaire pour tous les appels au tableau de chaînes

stringArrayRotate

Type: boolean Default: true

⚠️ stringArray doit être activé

Décale le tableau stringArray d'un nombre de positions fixe et aléatoire (généré lors de l'obfuscation du code). Cela rend plus difficile la mise en correspondance de l'ordre des chaînes retirées avec leur emplacement d'origine.

stringArrayShuffle

Type: boolean Default: true

⚠️ stringArray doit être activé

Mélange aléatoirement les éléments du tableau stringArray.

stringArrayWrappersCount

Type: number Default: 1

⚠️ l'option stringArray doit être activée

Définit le nombre de wrappers du string array dans chaque portée racine ou de fonction. Le nombre réel de wrappers dans chaque portée est limité par le nombre de nœuds literal présents dans cette portée.

Exemple :

// Input
const foo = 'foo';
const bar = 'bar';
        
function test () {
    const baz = 'baz';
    const bark = 'bark';
    const hawk = 'hawk';
}

const eagle = 'eagle';

// Output, stringArrayWrappersCount: 5
const _0x3f6c = [
    'bark',
    'bar',
    'foo',
    'eagle',
    'hawk',
    'baz'
];
const _0x48f96e = _0x2e13;
const _0x4dfed8 = _0x2e13;
const _0x55e970 = _0x2e13;
function _0x2e13(_0x33c4f5, _0x3f6c62) {
    _0x2e13 = function (_0x2e1388, _0x60b1e) {
        _0x2e1388 = _0x2e1388 - 0xe2;
        let _0x53d475 = _0x3f6c[_0x2e1388];
        return _0x53d475;
    };
    return _0x2e13(_0x33c4f5, _0x3f6c62);
}
const foo = _0x48f96e(0xe4);
const bar = _0x4dfed8(0xe3);
function test() {
    const _0x1c262f = _0x2e13;
    const _0x54d7a4 = _0x2e13;
    const _0x5142fe = _0x2e13;
    const _0x1392b0 = _0x1c262f(0xe7);
    const _0x201a58 = _0x1c262f(0xe2);
    const _0xd3a7fb = _0x1c262f(0xe6);
}
const eagle = _0x48f96e(0xe5);

stringArrayWrappersChainedCalls

Type: boolean Default: true

⚠️ les options stringArray et stringArrayWrappersCount doivent être activées

Active les appels chaînés entre les wrappers du string array.

Exemple :

// Input
const foo = 'foo';
const bar = 'bar';
        
function test () {
    const baz = 'baz';
    const bark = 'bark';

    function test1() {
        const hawk = 'hawk';
        const eagle = 'eagle';
    } 
}

// Output, stringArrayWrappersCount: 5, stringArrayWrappersChainedCalls: true
const _0x40c2 = [
    'bar',
    'bark',
    'hawk',
    'eagle',
    'foo',
    'baz'
];
const _0x31c087 = _0x3280;
const _0x31759a = _0x3280;
function _0x3280(_0x1f52ee, _0x40c2a2) {
    _0x3280 = function (_0x3280a4, _0xf07b02) {
        _0x3280a4 = _0x3280a4 - 0x1c4;
        let _0x57a182 = _0x40c2[_0x3280a4];
        return _0x57a182;
    };
    return _0x3280(_0x1f52ee, _0x40c2a2);
}
const foo = _0x31c087(0x1c8);
const bar = _0x31c087(0x1c4);
function test() {
    const _0x848719 = _0x31759a;
    const _0x2693bf = _0x31c087;
    const _0x2c08e8 = _0x848719(0x1c9);
    const _0x359365 = _0x2693bf(0x1c5);
    function _0x175e90() {
        const _0x310023 = _0x848719;
        const _0x2302ef = _0x2693bf;
        const _0x237437 = _0x310023(0x1c6);
        const _0x56145c = _0x310023(0x1c7);
    }
}

stringArrayWrappersParametersMaxCount

Type: number Default: 2

⚠️ l'option stringArray doit être activée
⚠️ Actuellement, cette option n'affecte que les wrappers ajoutés par la valeur function de l'option stringArrayWrappersType

Permet de contrôler le nombre maximal de paramètres des wrappers du tableau de chaînes. La valeur par défaut et minimale est 2. Valeur recommandée entre 2 et 5.

stringArrayWrappersType

Type: string Default: variable

⚠️ les options stringArray et stringArrayWrappersCount doivent être activées

Permet de sélectionner le type des wrappers ajoutés par l'option stringArrayWrappersCount.

Valeurs disponibles :

  • 'variable' : ajoute des wrappers de type variable en haut de chaque portée. Performances rapides.
  • 'function' : ajoute des wrappers de type fonction à des positions aléatoires dans chaque portée. Performances plus lentes qu'avec variable, mais offre une obfuscation plus stricte.

Il est fortement recommandé d'utiliser les wrappers function pour une obfuscation plus poussée lorsque la perte de performances n'a pas d'impact important sur l'application obfusquée.

Exemple avec la valeur 'function' :

// input
const foo = 'foo';

function test () {
    const bar = 'bar';
    console.log(foo, bar);
}

test();

// output
const a = [
    'log',
    'bar',
    'foo'
];
const foo = d(0x567, 0x568);
function b(c, d) {
    b = function (e, f) {
        e = e - 0x185;
        let g = a[e];
        return g;
    };
    return b(c, d);
}
function test() {
    const c = e(0x51c, 0x51b);
    function e (c, g) {
        return b(c - 0x396, g);
    }
    console[f(0x51b, 0x51d)](foo, c);
    function f (c, g) {
        return b(c - 0x396, g);
    }
}
function d (c, g) {
    return b(g - 0x3e1, c);
}
test();

stringArrayThreshold

Type: number Default: 0.8 Min: 0 Max: 1

⚠️ l'option stringArray doit être activée

Ce paramètre permet d'ajuster la probabilité (de 0 à 1) qu'un littéral de chaîne soit inséré dans le stringArray.

Ce paramètre est particulièrement utile pour les codes volumineux, car il génère de nombreux appels au string array et peut ralentir votre code.

stringArrayThreshold: 0 équivaut à stringArray: false.

strictMode

Type: boolean | null Default: null

Permet de spécifier la façon dont l'obfuscateur traite le code vis-à-vis du mode strict de JavaScript.

Valeurs disponibles :

  • null (par défaut) - détecte automatiquement le mode strict à partir du code. Si le code contient une directive 'use strict' explicite, une syntaxe de module ES ou des méthodes de classe, il est traité en mode strict. Sinon, le mode non strict (sloppy) est supposé.
  • true - force le traitement en mode strict pour tout le code, même sans directive 'use strict' explicite. À utiliser lorsque votre code s'exécutera dans un contexte de mode strict (par exemple dans des modules ES, des bundlers ou des frameworks modernes).
  • false - seuls les indicateurs de mode strict explicites ('use strict', modules ES, méthodes de classe) sont traités comme du mode strict. L'héritage de la portée parente s'applique toujours conformément à la spécification JS.

target

Type: string Default: browser

Permet de définir l'environnement cible du code obfusqué.

Valeurs disponibles :

  • browser (par défaut) — environnement de page web standard. Le code produit est identique à celui de node, mais certaines options propres au navigateur ne peuvent pas être utilisées avec la cible node
  • browser-no-eval — identique à browser, mais la sortie n'utilise pas eval(). À utiliser lorsque la page cible applique une Content Security Policy qui interdit eval/unsafe-eval.
  • node — environnement Node.js. Les options propres au navigateur sont désactivées (elles requièrent window/document et seraient sans effet ou lèveraient une erreur sous Node). Certaines défenses vmSelfDefending qui reposent sur des API exclusivement navigateur — détection de navigateur headless, restauration d'un realm propre via iframe, contrôles anti-inspecteur/DOM — ne sont pas générées pour cette cible.
  • service-worker — contexte Service Worker. Pas de window, pas de document, un global self différent.
  • userscript — bac à sable d'un gestionnaire de userscripts (Tampermonkey, par exemple). Les défenses vmSelfDefending sont ajustées en conséquence.
  • bytenode — code Node.js qui sera compilé avec le chargeur bytenode (bytecode V8 mis en cache .jsc) après l'obfuscation. L'obfuscateur lui-même n'invoque pas bytenode ; il produit un JavaScript obfusqué par VM dont le runtime est structuré pour survivre à l'étape de compilation de bytenode, et les défenses vmSelfDefending sont ajustées en conséquence. Exécutez vous-même bytenode sur la sortie obfusquée pour produire le fichier .jsc final.

transformObjectKeys

Type: boolean Default: false

Active la transformation des clés d'objet.

Exemple :

// input
(function(){
    var object = {
        foo: 'test1',
        bar: {
            baz: 'test2'
        }
    };
})();

// output
var _0x4735 = [
    'foo',
    'baz',
    'bar',
    'test1',
    'test2'
];
function _0x390c(_0x33d6b6, _0x4735f4) {
    _0x390c = function (_0x390c37, _0x1eed85) {
        _0x390c37 = _0x390c37 - 0x198;
        var _0x2275f8 = _0x4735[_0x390c37];
        return _0x2275f8;
    };
    return _0x390c(_0x33d6b6, _0x4735f4);
}
(function () {
    var _0x17d1b7 = _0x390c;
    var _0xc9b6bb = {};
    _0xc9b6bb[_0x17d1b7(0x199)] = _0x17d1b7(0x19c);
    var _0x3d959a = {};
    _0x3d959a[_0x17d1b7(0x198)] = _0x17d1b7(0x19b);
    _0x3d959a[_0x17d1b7(0x19a)] = _0xc9b6bb;
    var _0x41fd86 = _0x3d959a;
}());

warnings

Type: string | object Default: all

Contrôle quels avertissements d'obfuscation non fatals sont émis via la méthode ObfuscationResult.getWarnings().

Valeurs disponibles :

  • 'all' (par défaut) — chaque avertissement est émis.
  • 'none' — tous les avertissements sont supprimés.
  • un objet associant des types d'avertissement à des booléens — un type associé à false est supprimé ; tout type absent (ou associé à true) reste actif. Par exemple, { "VMGlobalFunctionNamesNotRenamed": false } conserve tous les avertissements sauf celui-ci.

Types d'avertissement :

  • VMGlobalFunctionNamesNotRenamed — sous vmObfuscation, les noms des déclarations de fonctions de premier niveau, des déclarations de classes et des variables auxquelles est affectée une expression de fonction/fléchée/classe ont été conservés tels quels (l'option renameGlobals est désactivée et le code n'est pas encapsulé dans une IIFE) ; ils restent donc lisibles dans la sortie même si les corps sont masqués sous forme de bytecode. Les noms exportés ne sont pas signalés.
  • VMTopLevelInitializerNotVirtualized — des initialiseurs de variables de premier niveau sont restés en JavaScript ordinaire sous obfuscation VM parce que vmWrapTopLevelInitializers est désactivé ou n'a pas pu les virtualiser.
  • DynamicCodeRenameRisk — le code construit une fonction à partir d'une chaîne à l'exécution (eval direct, constructeur Function, ou fn.toString() injecté dans un <script>/Worker), ce qui peut référencer des identifiants que l'obfuscateur a renommés.
  • VMDynamicCodeSkipped — une fonction a été exclue du bytecoding VM parce qu'elle contient un eval direct / un new Function dynamique / Function (voir vmForceCompileDynamicCode).
  • VMSyncFunctionSkippedInAsyncMode — avec vmAsyncExecutor activé, une fonction que vous aviez explicitement marquée en mode comment s'est avérée synchrone et a été ignorée (seules les fonctions asynchrones sont virtualisées dans ce mode).
  • VMAsyncGeneratorSkippedInAsyncMode — avec vmAsyncExecutor et un getter de clé asynchrone actif, un générateur asynchrone marqué n'a pas pu être virtualisé (il doit renvoyer son itérateur de façon synchrone).
  • BrowserTargetWithNodeStyleCode — le code semble cibler Node.js (par exemple require('fs'), __dirname, process.argv) alors que l'option target est réglée sur un environnement de type navigateur.

vmObfuscation

Type: boolean Default: false

Active l'obfuscation en bytecode basée sur une VM. Lorsqu'elle est activée, les fonctions JavaScript sont compilées en bytecode sur mesure qui s'exécute sur une machine virtuelle embarquée. Cela offre le plus haut niveau de protection, car la logique du code d'origine est entièrement transformée.

Exemple : Un code lisible comme return qty * price devient une liste de nombres comme [0x15,0x03,0x17,...] que seul l'interpréteur VM embarqué peut exécuter. La logique d'origine n'est plus visible sous forme de JavaScript.

vmTargetFunctions

Type: string[] Default: []

Indique précisément, par leur nom, quelles fonctions de premier niveau doivent bénéficier de la protection VM.

Exemple :

{
    vmObfuscation: true,
    vmTargetFunctions: ['someFunctionName']
}

Résultat : seules ces trois fonctions sont protégées par VM. Tout le reste demeure du JavaScript ordinaire (mais toujours obfusqué). Idéal pour protéger des vérifications de licence sensibles ou une logique d'authentification tout en gardant le reste de votre code léger.

vmExcludeFunctions

Type: string[] Default: []

Indique les fonctions de premier niveau qui ne doivent jamais bénéficier de la protection VM. Cette option a priorité sur les autres réglages.

Exemple :

{
    vmObfuscation: true,
    vmExcludeFunctions: ['someFunctionName']
}

Quand l'utiliser : les fonctions de premier niveau critiques pour les performances (boucles d'animation, traitement de données en temps réel) peuvent être exclues afin d'éviter la surcharge de la VM tout en protégeant tout le reste.

vmTargetFunctionsMode

Type: string Default: root

Contrôle la façon dont les fonctions/méthodes sont sélectionnées pour l'obfuscation VM.

ModeDescription
rootComportement par défaut. Seules les fonctions de premier niveau sont prises en compte pour l'obfuscation VM. Utilise la liste d'autorisation vmTargetFunctions et la liste d'exclusion vmExcludeFunctions pour filtrer.
commentSeules les fonctions/méthodes annotées du commentaire /* javascript-obfuscator:vm */ sont obfusquées par VM. Fonctionne avec les fonctions/méthodes à tout niveau d'imbrication.

Exemple - mode Comment :

// Source code
function regularFunction() {
    return 'not virtualized';
}

/* javascript-obfuscator:vm */
function sensitiveFunction() {
    return 'this will be VM-protected';
}

function outer() {
    /* javascript-obfuscator:vm */
    function nestedSensitive() {
        return 'nested but still VM-protected';
    }
    return nestedSensitive();
}
// Obfuscator options
{
    vmObfuscation: true,
    vmTargetFunctionsMode: 'comment'
}

Quand l'utiliser : lorsque vous avez besoin d'un contrôle chirurgical sur les fonctions qui bénéficient de la protection VM, en particulier des fonctions imbriquées contenant une logique sensible. Contrairement à vmTargetFunctions, qui ne fonctionne qu'avec des fonctions nommées de premier niveau, le mode comment vous permet de protéger n'importe quelle fonction, où qu'elle se trouve dans votre code.

vmForceCompileDynamicCode

Type: boolean Default: false

Contrôle ce que l'obfuscation VM fait d'une fonction contenant un appel direct à eval, new Function(...) ou Function(...).

Par défaut, une telle fonction (ainsi que toutes les fonctions qui y sont définies) est exclue du bytecoding VM et un avertissement VMDynamicCodeSkipped est signalé via result.getWarnings(). En effet, le source construit à l'exécution peut référencer des identifiants de la chaîne de portées environnante — des identifiants que l'obfuscateur a renommés.

Lorsqu'elle vaut true, la fonction est tout de même convertie en bytecode et l'avertissement VMDynamicCodeSkipped n'est plus émis.

L'avertissement distinct DynamicCodeRenameRisk continue de se déclencher quelle que soit cette option, car le risque de renommage qu'il décrit est indépendant de l'exclusion VM — activer cette option ne rend pas le motif sous-jacent plus sûr pour autant.

// Source code
function loadConfig(src) {
    return eval(src);
}
loadConfig('1 + 2');
// Options
{
    vmObfuscation: true,
    vmForceCompileDynamicCode: true
}

Avec l'option désactivée (par défaut), loadConfig reste en JavaScript ordinaire. Avec l'option activée, loadConfig est compilée en bytecode VM comme n'importe quelle autre fonction. Utilisez-la lorsque vous avez audité le site d'appel et que vous savez que le code construit à l'exécution ne dépend pas d'identifiants renommés par une closure.

vmWrapTopLevelInitializers

Type: boolean Default: false

Encapsule certains initialiseurs de variables de premier niveau dans des IIFE (expressions de fonction immédiatement invoquées) afin qu'ils puissent être obfusqués par VM.

Ce qu'elle fait : Sans cette option, les constantes et variables de premier niveau restent visibles dans la sortie :

// Input
const MY_STRING = "my-string";

// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string";  // String is visible!

Avec cette option activée, l'initialiseur est encapsulé dans une IIFE qui est obfusquée par VM :

// Input
const MY_STRING = "my-string";

// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })();  // String hidden in bytecode

Remarque : cette option ne fonctionne que lorsque vmTargetFunctionsMode vaut 'root' (la valeur par défaut).

Avertissements : chaque fois qu'un initialiseur de premier niveau se retrouve en JavaScript ordinaire sous obfuscation VM, un avertissement VMTopLevelInitializerNotVirtualized listant les noms des variables concernées est signalé. Cela couvre : cette option désactivée, les initialiseurs que cette option a dû ignorer (chacun accompagné de sa raison — par exemple l'initialiseur référence un déclarateur voisin ou contient un await de premier niveau), et le mode vmAsyncExecutor où les wrappers synchrones ne peuvent pas du tout être virtualisés.

vmDynamicOpcodes

Type: boolean Default: false

Rend l'interpréteur VM plus petit et unique à chaque build.

Ce qu'elle fait :

  1. Filtre les instructions inutilisées - Si votre code n'utilise pas de classes, les instructions liées aux classes sont entièrement supprimées
  2. Rend la structure aléatoire - L'ordre des gestionnaires d'instructions est mélangé à chaque build

En conséquence, la sortie est plus petite et chaque build a une apparence différente.

vmBytecodeEncoding

Type: boolean Default: false

Encode chaque instruction du bytecode. Les instructions sont décodées une par une pendant l'exécution.

vmBytecodeArrayEncoding

Type: boolean Default: false

Encode l'intégralité du tableau de bytecode en un seul bloc. Le tableau est décodé une seule fois au démarrage, avant le début de l'exécution. À utiliser conjointement avec vmBytecodeEncoding pour obtenir deux couches de protection.

vmBytecodeArrayEncodingKey

Type: string Default: ''

Clé de chiffrement personnalisée pour l'encodage du tableau de bytecode. Lorsqu'elle est définie, cette clé est utilisée à la place de la clé par défaut dérivée de l'environnement. La clé doit être fournie à l'exécution via vmBytecodeArrayEncodingKeyGetter.

Cette option externalise la clé de chiffrement : elle n'est pas intégrée au code obfusqué lui-même. Bien que la clé reste accessible à l'exécution (et ne soit donc pas véritablement secrète), cette séparation empêche les outils d'analyse statique de retrouver la clé en examinant le seul code.

Important : la clé doit être disponible de façon synchrone au chargement du code obfusqué. Utilisez un stockage synchrone comme les cookies, localStorage, sessionStorage, des variables globales ou des éléments du DOM (par exemple des balises meta injectées par le serveur). Les méthodes asynchrones comme fetch() ne peuvent pas être utilisées directement dans l'expression du getter de clé.

vmBytecodeArrayEncodingKeyGetter

Type: string Default: ''

Expression JavaScript synchrone qui renvoie la clé de chiffrement à l'exécution. Cette expression est évaluée au chargement du code obfusqué et doit renvoyer la même clé que celle fournie dans vmBytecodeArrayEncodingKey. Pour résoudre la clé de façon asynchrone (une Promise), activez vmAsyncExecutor.

Remarque : un getter renvoyant une Promise nécessite vmAsyncExecutor. Cela ne peut pas être vérifié au moment du build ; un getter renvoyant une Promise avec vmAsyncExecutor désactivé échoue donc à l'exécution — le décodeur reçoit la Promise au lieu de la clé.

Le code obfusqué ne fonctionne que si le getter de clé renvoie exactement la même clé que celle utilisée lors de l'obfuscation. Si les clés ne correspondent pas, le déchiffrement échoue et le code produit des résultats erronés ou des erreurs. Si le getter de clé renvoie undefined, null ou une chaîne vide, le code lève une erreur : "VM decryption key not available".

Important : ne conservez pas la clé dans le même fichier/script que le code obfusqué — l'y intégrer permet à un simple examen statique du bundle de la retrouver. Stockez-la plutôt dans une source distincte : cookies définis par le serveur, localStorage renseigné par un autre script, balise meta HTML injectée par le serveur, variable globale définie par un autre script, ou (avec vmAsyncExecutor) récupérée depuis votre backend à l'exécution.

Lorsque la clé est récupérée depuis votre backend (via vmAsyncExecutor), ajoutez des contrôles fondés sur la session ou l'origine sur ce point de terminaison : renvoyez la bonne clé aux utilisateurs réels (session valide, Origin/Referer attendus) et une clé factice aux requêtes suspectes (par exemple une origine localhost/inattendue, absence de session). Les utilisateurs réels s'exécutent normalement ; une copie exécutée en dehors de votre environnement obtient une clé qui ne déchiffre rien. La logique exacte dépend de votre site.

Exemples :

// From cookie
vmBytecodeArrayEncodingKeyGetter: "document.cookie.match(/vmKey=([^;]+)/)?.[1]"

// From localStorage
vmBytecodeArrayEncodingKeyGetter: "localStorage.getItem('vmKey')"

// From global variable
vmBytecodeArrayEncodingKeyGetter: "window.__VM_KEY__"

// From meta tag (server-injected)
vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]').content"

// From nested object
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"

// From backend, async (requires vmAsyncExecutor)
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'

Exemple d'utilisation :

// Build time
JavaScriptObfuscator.obfuscate(code, {
    vmObfuscation: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: 'mySecretKey123',
    vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
});

// Runtime - key must be set before obfuscated code runs
window.__VM_KEY__ = 'mySecretKey123';

vmAsyncExecutor

Type: boolean Default: false

Active l'exécuteur VM asynchrone, qui permet à vmBytecodeArrayEncodingKeyGetter de renvoyer une Promise (un getter de clé asynchrone) — la clé de déchiffrement peut ainsi être récupérée à l'exécution (requête réseau, IndexedDB, etc.) au lieu de devoir être disponible de façon synchrone au chargement du code.

Fortement recommandé pour les bases de code entièrement asynchrones. Dans ce mode, seules les fonctions async sont virtualisées — une fonction synchrone ne peut pas être rendue asynchrone sans transformer sa valeur de retour en Promise et casser ses appelants — de sorte qu'un code async de bout en bout obtient la meilleure couverture. Cela fonctionne tout de même lorsque la racine est synchrone (par exemple une IIFE synchrone / un wrapper UMD) : les fonctions async les plus externes qu'elle contient sont protégées, et les parties synchrones sont laissées telles quelles.

Ce qui est transformé : chaque fonction async la plus externe, où qu'elle apparaisse (y compris imbriquée dans des wrappers synchrones). L'async la plus externe de chaque chaîne est l'unité protégée — tout ce qu'elle contient, synchrone comme asynchrone, y est compilé. Les fonctions synchrones et les générateurs simples restent non obfusqués.

function foo() {              // sync — left as-is
    function bar() {}         // sync — left as-is

    async function baz() {    // transformed
        // any code here, including calls to other async or sync functions
    }

    async function bark() {   // transformed
        // any code here, including calls to other async or sync functions
    }
}

Exclusions et avertissements. Les générateurs asynchrones restent eux aussi non obfusqués lorsqu'un getter de clé asynchrone est actif (un générateur asynchrone doit renvoyer son itérateur de façon synchrone et ne peut pas attendre la clé). Dans le mode par défaut vmTargetFunctionsMode: 'root', les exclusions sont silencieuses (la sélection est automatique) ; en mode comment, un avertissement est émis via ObfuscationResult.getWarnings() chaque fois qu'une fonction que vous avez explicitement marquée ne peut pas être virtualisée — elle s'est avérée synchrone, ou il s'agit d'un générateur asynchrone sous un getter de clé asynchrone.

Le getter de clé asynchrone nécessite en outre vmBytecodeArrayEncoding avec un vmBytecodeArrayEncodingKeyGetter.

Exemple d'utilisation :

JavaScriptObfuscator.obfuscate(code, {
    vmObfuscation: true,
    vmAsyncExecutor: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: 'mySecretKey123',
    // the key getter may now return a Promise
    vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
});

vmJumpsEncoding

Type: boolean Default: false

Encode les cibles de saut dans le bytecode. Les décalages de saut sont calculés à l'exécution, masquant la structure du flux de contrôle (if/else, boucles, etc.) à l'analyse statique.

vmMacroOps

Type: boolean Default: false

Combine des séquences d'instructions courantes en opcodes « macro » uniques. Par exemple, LOAD + ADD + STORE peut devenir une seule instruction MACRO_ADD_TO_VAR. Cela déjoue la reconnaissance de motifs et peut améliorer les performances.

vmDebugProtection

Type: boolean Default: false

Ajoute au runtime de la VM des défenses multicouches anti-débogage, anti-analyse et anti-LLM. Fonctionne au mieux avec les cibles browser/browser-no-eval.

vmSelfDefending

Type: boolean Default: false

Ajoute au runtime de la VM une protection multicouche de détection des altérations, anti-hooking et anti-rétro-ingénierie.

⚠️ Cette option active de force vmBytecodeArrayEncoding.

⚠️ Détection d'environnements sensibles. Cette option lie le code obfusqué à son environnement d'exécution cible et utilise un fingerprinting avancé du navigateur pour détecter les outils d'automatisation. Un code protégé par cette option se cassera intentionnellement lorsqu'il sera exécuté dans :

  • Des navigateurs headless (Chrome/Chromium headless, PhantomJS)
  • Des outils d'automatisation de navigateur (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
  • Node.js (lorsque target vaut browser)
  • jsdom ou d'autres émulations du DOM côté serveur
  • Des environnements où des fonctions natives du navigateur ont été hookées ou remplacées

Le code fonctionnera correctement dans les navigateurs classiques (Chrome, Firefox, Safari, Edge), y compris lorsqu'il est chargé dans des iframes, des extensions de navigateur (content scripts) et des Web Workers. Si vous devez exécuter des tests automatisés sur du code protégé, désactivez vmSelfDefending pour les builds de test — cette option est conçue pour empêcher l'analyse automatisée et ne peut pas être utilisée en toute sécurité avec un quelconque framework d'automatisation.

Il est fortement recommandé de l'utiliser conjointement avec vmDebugProtection, vmBytecodeArrayEncodingKey et vmBytecodeArrayEncodingKeyGetter.

vmDefenseHook

Type: { name: string, aliases?: object } Default: ''

vmDefenseHook prend un objet à deux clés : name (obligatoire) et aliases (facultatif).

name est une fonction globale définie par votre page hôte qu'une défense de la VM (vmDebugProtection / vmSelfDefending) appelle avec un objet signal lorsqu'elle détecte un signal hostile — un débogueur ou un inspecteur, un navigateur headless / d'automatisation, un processus d'agent de codage IA, un domaine non autorisé, etc. Utilisez-la pour remonter l'événement vers votre backend (par exemple via navigator.sendBeacon). Le hook est un simple puits de télémétrie : sa valeur de retour est ignorée, et un hook absent ou qui lève une exception est un no-op silencieux qui ne peut jamais désactiver une défense. Pour changer ce que fait une défense lors d'une détection, utilisez vmDefenseReaction.

aliases renomme facultativement les champs de cet objet signal — abordé plus bas dans Renommer les champs du signal.

L'objet signal. Le hook reçoit un unique signal :

  • source — le détecteur précis qui s'est déclenché (voir le tableau).
  • category — le groupe sous lequel il remonte : automation (navigateurs non humains), debugger (un débogueur/inspecteur est actif), sandbox (hôte instrumenté/factice), domain (violation du verrouillage par domaine), tamper (fonctions intégrées modifiées à l'exécution) ou integrity (le code propre de la VM a été altéré).
  • score / threshold — l'intensité du déclenchement du détecteur et la valeur qu'il devait atteindre ; le hook ne se déclenche qu'une fois score >= threshold. La plupart des contrôles sont tout ou rien (un unique signal décisif) ; headless additionne plusieurs signaux liés à la forme du navigateur, si bien que son score est généralement supérieur à son threshold.
sourcedétectecategory
integrityle code VM obfusqué lui-même a été modifiéintegrity
nodedu code destiné au navigateur s'exécutant sous Node.jsdebugger
debuggerune session de débogueur ou d'inspecteur attachée ou active, ou un environnement de débogagedebugger
headlessun navigateur headless est utilisé pour exécuter le codeautomation
agentun agent de codage IA exécutant le codeautomation
timingune pause d'exécution suggérant un point d'arrêt ou un débogueur en pas à pasdebugger
sandboxle code s'exécute dans un bac à sable ou un environnement hôte facticesandbox
domainl'origine de la page n'est pas dans la liste d'autorisation vmDomainLockdomain
nativeHookune fonction native intégrée a été remplacée ou hookéetamper

Enregistrement du hook. Définissez-le comme une simple globale avant le chargement du bundle obfusqué — le runtime de la VM et ses défenses s'exécutent avant votre programme (protégé), de sorte que de nombreuses détections se produisent au démarrage :

// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }

Un hook défini à l'intérieur du source obfusqué est enregistré trop tard pour intercepter les détections du démarrage et, s'il est compilé par la VM, il reste inaccessible tant que votre programme n'a pas démarré. Il reste sans danger dans tous les cas (un hook absent est un no-op, et un garde-fou anti-réentrance empêche tout emballement), mais pour une couverture complète, enregistrez-le en amont. Pour tout de même protéger votre logique de remontée, gardez comme hook enregistré un tampon d'une ligne ((window.__vmDet = window.__vmDet || []).push(signal)) et lisez/envoyez ce tampon depuis votre code obfusqué.

Renommer les champs du signal (aliases). Les valeurs source/category par défaut sont des noms descriptifs : quiconque instrumente le callback (ou lit la sortie) peut donc reconnaître la protection et le détecteur qui s'est déclenché. aliases remplace les noms des champs du signal par des jetons opaques de votre choix, appliqués à l'intérieur de la VM avant l'émission du signal, de sorte que ces noms n'apparaissent jamais dans la sortie ni ne parviennent au callback. Votre application connaît sa propre correspondance et transmet les jetons à votre backend.

Les alias se définissent champ par champ, en séparant le renommage des clés de celui des valeurs : chaque champ accepte une key (le nom de propriété que reçoit le callback) ; les champs de type chaîne source et category acceptent en plus une table values, tandis que score / threshold sont des nombres et n'acceptent qu'une key. Les noms que vous pouvez mapper (tout autre est rejeté au moment du build) :

  • clés de champsource, category, score, threshold
  • valeurs de sourceheadless, agent, node, debugger, timing, sandbox, domain, nativeHook, integrity
  • valeurs de categoryautomation, debugger, sandbox, domain, tamper, integrity
vmDefenseHook: {
    name: '__vmDetection',
    aliases: {
        source:    { key: 'a8Qm', values: { headless: 'xP4m9Q' } },
        category:  { key: 'p3Tx', values: { automation: 'bQ7s1M' } },
        score:     { key: 's1' },
        threshold: { key: 't1' }
    }
    // the callback now receives e.g. { a8Qm: 'xP4m9Q', p3Tx: 'bQ7s1M', s1: <score>, t1: <threshold> }
}

Il s'agit d'une gêne à l'identification, pas d'un secret — la correspondance peut toujours être déduite par tâtonnements répétés — de sorte que son seul bénéfice est de ne pas exposer des noms stables et explicites. Les entrées non renseignées conservent leur nom par défaut.

Une chaîne simple (vmDefenseHook: '__vmDetection') est acceptée comme raccourci de { name: '__vmDetection' } mais est dépréciée — préférez la forme objet.

vmDefenseReaction

Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }

Configure la façon dont chaque catégorie de détection réagit. Elle n'active rien — les défenses elles-mêmes sont activées par vmSelfDefending, vmDebugProtection et vmDomainLock ; cette option ne fait que choisir comment réagit une défense déjà activée. La catégorie est l'unité de contrôle — chaque détecteur d'une catégorie applique la réaction de cette catégorie.

Chaque catégorie regroupe les détecteurs qui surveillent un même type de condition hostile. Une catégorie ne réagit que lorsque l'option qui émet ses détecteurs est activée :

CatégorieActivée parRéagit lorsque
automationvmSelfDefending ou vmDebugProtectionLe code est piloté par un logiciel et non par une personne : navigateur headless ou automatisé, framework de scraping ou de test, ou agent de codage IA parcourant la page pas à pas.
debuggervmDebugProtection ou vmSelfDefendingQuelqu'un a ouvert un débogueur ou l'inspecteur des outils de développement du navigateur et parcourt le code en cours d'exécution pour le comprendre.
sandboxvmDebugProtectionLe code ne s'exécute pas du tout dans un vrai navigateur — il a été transposé dans un environnement JavaScript émulé ou scripté afin d'être exécuté et étudié hors ligne.
domainvmDomainLockLe code s'exécute sur un site que vous n'avez pas autorisé : un hôte absent de votre liste d'autorisation vmDomainLock (par exemple votre bundle copié sur le domaine d'un tiers).
tampervmSelfDefendingL'environnement JavaScript autour de la VM a été modifié pour l'observer ou la détourner, par exemple en remplaçant des fonctions natives du navigateur par des versions instrumentées.
integrityvmSelfDefendingLe code du bundle protégé lui-même a été modifié ou patché depuis que vous l'avez généré.

Chaque catégorie correspond à une ou plusieurs des options vmSelfDefending, vmDebugProtection et vmDomainLock ; il n'existe aucune catégorie en dehors de ces trois options, et une réaction définie pour une catégorie dont l'option est désactivée n'a tout simplement aucun effet.

Les clés sont ces six noms de catégories, ou default (valeur de repli pour les catégories non spécifiées). Les valeurs sont :

  • break — rompre immédiatement
  • decoy — continuer à s'exécuter sur un état empoisonné, en produisant silencieusement des résultats erronés
  • none — ne rien faire localement (télémétrie uniquement)

Les valeurs par défaut par catégorie sont indiquées ci-dessus ; une catégorie que vous ne définissez pas (ou que vous laissez à sa valeur par défaut) utilise cette valeur par défaut. default atteint toutes les catégories, y compris celles qui sont correctes par construction (integrity, tamper) ; { default: 'none' } produit donc un build véritablement non intrusif, purement télémétrique :

vmDefenseReaction: { default: 'none' }              // never break — pair with vmDefenseHook
vmDefenseReaction: { automation: 'none', domain: 'break' }   // tolerate automation FPs, still break on a bad domain

vmStatefulOpcodes

Type: boolean Default: false

Fait dépendre la signification des opcodes de leur position dans le bytecode. Chaque position possède une correspondance opcode-vers-gestionnaire différente, dérivée d'une graine, de sorte qu'un même numéro d'opcode effectue des opérations différentes selon la position.

vmCallContextOpcodes

Type: boolean Default: false

Fait dépendre une fonction protégée de l'endroit d'où elle est appelée, de sorte qu'elle ne peut pas être extraite du code puis exécutée ou analysée isolément — elle ne se comporte correctement que lorsqu'elle est invoquée via ses véritables sites d'appel dans le programme. Cette option affecte les performances à l'exécution.

Actuellement, seules les constructions suivantes sont prises en charge :

  • les déclarations de fonction (function f() {}) ;
  • les expressions de fonction et les fonctions fléchées affectées à une variable (const f = () => {}) ;
  • les méthodes privées d'instance (this.#m()).

Dans tous les cas, la fonction doit toujours être atteinte par un appel direct (f(), this.#m()). Si elle est stockée dans une autre variable, passée en argument ou utilisée d'une autre manière comme valeur, elle reste non protégée. Les fonctions asynchrones sont prises en charge ; les générateurs ne le sont pas.

Cette option est expérimentale et peut casser votre code ; testez donc soigneusement la sortie avant de l'utiliser.

vmStackEncoding

Type: boolean Default: false

Chiffre les valeurs présentes sur la pile de la VM pendant l'exécution. Les valeurs sont encodées lorsqu'elles sont empilées et décodées lorsqu'elles sont dépilées, de sorte qu'une inspection de la mémoire montre des données chiffrées au lieu des valeurs réelles.

Cette option affecte fortement les performances.

vmCompactDispatcher

Type: boolean Default: false

Utilise un seul exécuteur VM au lieu de deux exécuteurs (synchrone + générateur). Réduit la taille du code obfusqué mais ajoute une surcharge d'environ 20 % sur un code fortement récursif.

  • false (par défaut) : deux exécuteurs — performances optimales, sortie plus volumineuse
  • true : un seul exécuteur — sortie plus petite, légèrement plus lente

vmStringArrayBytecodeOnly

Type: boolean Default: false

Lorsqu'elle est activée, le tableau de chaînes n'extrait que les chaînes issues des données de bytecode — aucune autre chaîne du code n'est transformée. Cela active de force stringArray même s'il n'est pas explicitement défini.

Pourquoi l'utiliser : extraire toutes les chaînes du runtime de la VM vers un tableau de chaînes est lent. Cette option ne cible que le contenu du bytecode pour l'extraction dans le tableau de chaînes, améliorant les performances tout en protégeant les constantes du bytecode.

  • Lorsque vmBytecodeArrayEncoding: false — les chaînes présentes dans les pools de constantes du bytecode (tableaux c) sont extraites
  • Lorsque vmBytecodeArrayEncoding: true — les chaînes de bytecode encodées en base64 au niveau supérieur sont extraites
  • stringArrayThreshold continue de contrôler le pourcentage de ces chaînes de bytecode qui sont extraites

vmDomainLock

Type: string[] Default: []

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Restreint le code obfusqué à des domaines et/ou sous-domaines précis, et est bien plus difficile à localiser et à retirer que domainLock.

Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à vmDomainLockRedirectUrl, et les appels protégés ultérieurs renverront des résultats incorrects même si la redirection est supprimée.

Domaines et sous-domaines multiples

Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.

vmDomainLockRedirectUrl

Type: string Default: about:blank

⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'

Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par vmDomainLock.

Options de préréglage

Obfuscation élevée, performances faibles

Les performances seront bien plus lentes que sans obfuscation

{
    compact: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 1,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 1,
    debugProtection: true,
    debugProtectionInterval: 4000,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: true,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: true,
    splitStringsChunkLength: 5,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: true,
    stringArrayEncoding: ['rc4'],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 5,
    stringArrayWrappersChainedCalls: true,    
    stringArrayWrappersParametersMaxCount: 5,
    stringArrayWrappersType: 'function',
    stringArrayThreshold: 1,
    transformObjectKeys: true
}

Obfuscation moyenne, performances optimales

Les performances seront plus lentes que sans obfuscation

{
    compact: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 0.75,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 0.4,
    debugProtection: false,
    debugProtectionInterval: 0,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: true,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: true,
    splitStringsChunkLength: 10,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: true,
    stringArrayCallsTransformThreshold: 0.75,
    stringArrayEncoding: ['base64'],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 2,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 4,
    stringArrayWrappersType: 'function',
    stringArrayThreshold: 0.75,
    transformObjectKeys: true
}

Obfuscation faible, performances élevées

Les performances resteront à un niveau relativement normal

{
    compact: true,
    controlFlowFlattening: false,
    deadCodeInjection: false,
    debugProtection: false,
    debugProtectionInterval: 0,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: false,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: false,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: false,
    stringArrayEncoding: [],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 1,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 2,
    stringArrayWrappersType: 'variable',
    stringArrayThreshold: 0.75
}

Préréglage par défaut, performances élevées

{
    compact: true,
    controlFlowFlattening: false,
    deadCodeInjection: false,
    debugProtection: false,
    debugProtectionInterval: 0,
    disableConsoleOutput: false,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: false,
    renameGlobals: false,
    selfDefending: false,
    simplify: true,
    splitStrings: false,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: false,
    stringArrayCallsTransformThreshold: 0.5,
    stringArrayEncoding: [],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 1,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 2,
    stringArrayWrappersType: 'variable',
    stringArrayThreshold: 0.75
}

Obfuscation VM Ultra High (sécurité maximale)

Ce préréglage active l'obfuscation en bytecode basée sur une VM avec toutes les fonctionnalités de durcissement, y compris la répartition indirecte. Offre la protection la plus forte, mais avec une taille de sortie plus importante et une exécution bien plus lente.

{
    optionsPreset: 'vm-ultra-high-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,

    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,

    vmBytecodeEncoding: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: true,
    vmMacroOps: true,
    vmDebugProtection: true,
    vmSelfDefending: true,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: true,
    vmCallContextOpcodes: false,
    vmStackEncoding: true,
    vmCompactDispatcher: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 0.5,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 0.5,
    debugProtection: true,
    debugProtectionInterval: 4000,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    numbersToExpressions: true,
    renameGlobals: false,
    selfDefending: true,
    simplify: true,
    splitStrings: true,
    splitStringsChunkLength: 5,
    strictMode: null,
    stringArray: true,
    stringArrayCallsTransform: true,
    stringArrayEncoding: ['rc4'],
    stringArrayIndexShift: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayWrappersCount: 5,
    stringArrayWrappersChainedCalls: true,
    stringArrayWrappersParametersMaxCount: 5,
    stringArrayWrappersType: 'function',
    stringArrayThreshold: 0.5,
    transformObjectKeys: true
}

VM Anti-LLM (protection contre les agents IA)

Ce préréglage est spécifiquement conçu pour empêcher les agents IA et les LLM de rétro-concevoir du code en bytecode VM. Basé sur vm-default, avec l'auto-défense et la protection anti-débogage activées. Plus léger que vm-high-obfuscation, mais spécifiquement durci contre l'analyse automatisée.

{
    optionsPreset: 'vm-anti-llm'
}

Inclut :

  • l'obfuscation en bytecode VM avec tableau de chaînes (depuis vm-default)
  • vmSelfDefending — détection anti-hook, hash d'intégrité, empreinte de source, vérification d'un realm propre via iframe, dérivation de clé par chiffrement ARX
  • vmDebugProtection — contrôles anti-débogage dans la boucle de répartition de la VM
  • debugProtection: false — pas de protection anti-débogage héritée (la protection anti-débogage de la VM est supérieure)

Obfuscation VM High (sécurité la plus élevée)

Ce préréglage active l'obfuscation en bytecode basée sur une VM avec la plupart des fonctionnalités de durcissement. Offre une protection forte avec de meilleures performances que le préréglage ultra-high.

{
    optionsPreset: 'vm-high-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,
    vmBytecodeEncoding: true,
    vmBytecodeArrayEncoding: true,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: true,
    vmMacroOps: true,
    vmDebugProtection: true,
    vmSelfDefending: true,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: true,
    vmCallContextOpcodes: false,
    vmStackEncoding: true,
    vmCompactDispatcher: false
}

Obfuscation VM Medium (sécurité équilibrée)

Ce préréglage active l'obfuscation en bytecode basée sur une VM avec un ensemble équilibré de fonctionnalités de durcissement. Bon compromis entre sécurité et performances.

{
    optionsPreset: 'vm-medium-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,
    vmBytecodeEncoding: true,
    vmBytecodeArrayEncoding: false,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: true,
    vmMacroOps: true,
    vmDebugProtection: true,
    vmSelfDefending: false,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: false,
    vmCallContextOpcodes: false,
    vmStackEncoding: false,
    vmCompactDispatcher: false
}

Obfuscation VM Low (sécurité de base, meilleures performances)

Ce préréglage active une obfuscation en bytecode VM de base, sans fonctionnalités de durcissement supplémentaires. Bon équilibre entre sécurité et taille de sortie.

{
    optionsPreset: 'vm-low-obfuscation'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: false,
    vmBytecodeEncoding: false,
    vmBytecodeArrayEncoding: false,
    vmBytecodeArrayEncodingKey: '',
    vmBytecodeArrayEncodingKeyGetter: '',
    vmAsyncExecutor: false,
    vmJumpsEncoding: false,
    vmMacroOps: false,
    vmDebugProtection: false,
    vmSelfDefending: false,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: false,
    vmCallContextOpcodes: false,
    vmStackEncoding: false,
    vmCompactDispatcher: false
}

VM Default (VM + protection du tableau de chaînes)

Ce préréglage combine une obfuscation en bytecode VM de base avec la protection par tableau de chaînes. Bon point de départ pour l'obfuscation VM avec protection des chaînes.

{
    optionsPreset: 'vm-default'
}

Ou configurez individuellement :

{
    compact: true,
    simplify: true,
    identifierNamesGenerator: 'mangled-shuffled',
    vmObfuscation: true,
    vmForceCompileDynamicCode: false,
    vmWrapTopLevelInitializers: true,
    vmDynamicOpcodes: true,
    vmBytecodeEncoding: false,
    vmBytecodeArrayEncoding: true,
    vmStringArrayBytecodeOnly: true,
    vmAsyncExecutor: false,
    vmJumpsEncoding: false,
    vmMacroOps: false,
    vmDebugProtection: false,
    vmSelfDefending: false,
    vmDefenseHook: '',
    vmDefenseReaction: {
        automation: 'break',
        debugger: 'decoy',
        sandbox: 'decoy',
        domain: 'break',
        tamper: 'break',
        integrity: 'break'
    },
    vmStatefulOpcodes: false,
    vmCallContextOpcodes: false,
    vmStackEncoding: false,
    vmCompactDispatcher: false,
    stringArray: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayThreshold: 1,
    stringArrayIndexShift: true,
    stringArrayIndexesType: ['hexadecimal-number'],
    stringArrayCallsTransform: true,
    stringArrayCallsTransformThreshold: 1,
    stringArrayWrappersCount: 3,
    stringArrayWrappersType: 'function',
    stringArrayWrappersParametersMaxCount: 5,
    stringArrayWrappersChainedCalls: true,
    stringArrayEncoding: ['base64'],
    splitStrings: true,
    splitStringsChunkLength: 6
}