Module vm de Node.js

Java FileModules intégrés de Node.js


de Node.jsvmLe module est un module de machine virtuelle pour JavaScript, qui vous permet de compiler et d'exécuter du code dans un contexte de machine virtuelle V8. Ce module fournit un moyen d'exécuter du code JavaScript dans un contexte isolé, isolé du processus actuel mais capable d'utiliser un contexte spécifique.

Fonctionnalités principales

  • Environnement d'exécution isolé: Permet de créer un environnement de bac à sable isolé du programme principal
  • Contexte contrôlable: Permet de personnaliser les objets globaux et le contexte
  • Exécution sécurisée: Réduit l'impact du code non fiable sur le programme principal
  • Optimisation des performances: Peut précompiler les scripts pour améliorer l'efficacité des exécutions répétées

Introduction à l'API principale

Classe vm.Script

vm.ScriptCette classe est utilisée pour compiler du code sans l'exécuter. Le script compilé peut être exécuté plusieurs fois.

Exemple

const vm = require('vm');

const script = new vm.Script('x + y', {
  filename: 'add.vm',
  lineOffset: 0,
  displayErrors: true
});

Description du paramètre

  • code: La chaîne de code JavaScript à compiler
  • options(Facultatif) :
    • filename: Nom de fichier utilisé pour les traces de pile
    • lineOffset: Décalage du numéro de ligne de la première ligne du script
    • columnOffset: Décalage de colonne de la première colonne du script
    • displayErrors: Indique s'il faut afficher les erreurs sur stderr lorsque des erreurs se produisent
    • timeout: Délai d'exécution (millisecondes)
    • cachedData: Contient des données facultatives de cache de code V8

vm.createContext([contextObject])

Crée un nouvel objet de contexte, en utilisant éventuellement un objet existant pour l'initialisation.

Exemple

const context = vm.createContext({
  x: 10,
  y: 20
});

script.runInContext(contextifiedObject[, options])

Exécute le script compilé dans le contexte spécifié.

Exemple

const result = script.runInContext(context);
console.log(result); // Affiche 30

Cas d'utilisation

1. Exécuter en toute sécurité du code non fiable

Exemple

const vm = require('vm');

const untrustedCode = `
  process.exit(1); // Code malveillant
`;

try {
  const script = new vm.Script(untrustedCode);
  const context = vm.createContext({});
  script.runInContext(context);
} catch (err) {
  console.log('Interception de sécurité :', err.message);
}

2. Créer un environnement de test isolé

Exemple

const vm = require('vm');

const testCode = `
  function add(a, b) {
    return a + b;
  }
  ajoutez(2, 3);
`;

const context = vm.createContext({});
const result = vm.runInContext(testCode, context);
console.log('Résultat du test :', result); // Affiche 5

3. Implémentation du moteur de template

Exemple

const vm = require('vm');

function render(template, data) {
  const code = `\`${template}\``;
  const context = vm.createContext(data);
  return vm.runInContext(code, context);
}

const template = 'Bonjour, ${name} ! Vous avez ${age} ans.';
const result = render(template, { name: 'Alice', age: 25 });
console.log(result); // Affiche "Bonjour, Alice ! Vous avez 25 ans."

Considérations de sécurité

Bien quevmle module offre un certain degré d'isolation, ce n'est pas un bac à sable complètement sécurisé :

  1. Limite de mémoire: Le code malveillant peut encore causer un épuisement de la mémoire
  2. Opérations synchrones: Les boucles infinies bloqueront la boucle d'événements
  3. Évasion de contexte: Dans certains cas, les objets globaux peuvent être accessibles

Pour les scénarios nécessitant une sécurité plus élevée, envisagez :

  • Utilisez une isolation au niveau du système d'exploitation telle que les conteneurs Docker
  • Utilisez des solutions de bac à sable spécialisées telles que lesandboxmodule
  • Limitez le temps d'exécution et l'utilisation des ressources

Conseils d'optimisation des performances

1. Réutiliser les scripts compilés

Exemple

const vm = require('vm');
const script = new vm.Script('x * y');

// Exécuter le même script compilé plusieurs fois
for (let i = 0; i < 100; i++) {
  const context = vm.createContext({ x: i, y: 2 });
  console.log(script.runInContext(context));
}

2. Utiliser cachedData pour accélérer la compilation

Exemple

const vm = require('vm');

// Compiler pour la première fois et obtenir les données de cache
const script1 = new vm.Script('x + y');
const cachedData = script1.createCachedData();

// Utiliser plus tard les données du cache pour accélérer la compilation
const script2 = new vm.Script('x + y', { cachedData });

3. Définir un délai d’attente raisonnable

Exemple

const script = new vm.Script('while(true) {}', { timeout: 100 });
try {
  script.runInContext(vm.createContext({}));
} catch (err) {
  console.log('Délai d’exécution dépassé :', err.message);
}

Différences avec eval

Fonctionnalité module vm eval
Environnement d'exécution Peut créer un contexte isolé Utilise la portée actuelle
Sécurité Relativement élevée Relativement faible
Performance Peut être précompilé, avec une grande efficacité pour les exécutions répétées Nécessite une analyse syntaxique à chaque fois
Prise en charge du débogage Prend en charge la correspondance des noms de fichiers et des numéros de ligne Non pris en charge
Contrôle des ressources Peut définir des limites telles qu'un délai d'expiration Aucun contrôle

Résumé

de Node.jsvmLe module est un outil puissant, particulièrement adapté aux scénarios qui nécessitent une exécution isolée de code JavaScript. Bien qu'il ne s'agisse pas d'une solution de bac à sable totalement sécurisée, il offre dans de nombreux cas des capacités suffisantes d'isolation de sécurité et d'optimisation des performances. Lorsqu'il est utilisé correctement, il peut grandement améliorer la sécurité et la flexibilité des applications.

Java FileModules intégrés de Node.js

Autres extensions