Question

Une partie de notre application java doit exécuter du javascript écrit par des non-développeurs. Ces non-développeurs utilisent javascript pour le formatage des données. (Logique simple et concaténation de chaînes principalement).

Ma question est de savoir comment puis-je configurer l'exécution de ces scripts pour m'assurer que les erreurs de script n'ont pas d'impact négatif majeur sur le reste de l'application.

  • Nécessité de se prémunir contre des boucles infinies
  • Protégez-vous contre la création de nouveaux threads.
  • Limiter l'accès aux services et à l'environnement
    • Système de fichiers (Exemple: si un auteur de script mécontent a décidé de supprimer des fichiers)
    • Base de données (même chose, supprimer des enregistrements de base de données)

En gros, je dois configurer la portée de javascript pour inclure uniquement ce dont ils ont besoin, sans plus.

Était-ce utile?

La solution

Pour vous protéger contre les boucles infinies, vous devez le placer dans un processus séparé pour pouvoir le tuer.

Pour vous protéger contre la création de threads, vous devez étendre SecurityManager (l'implémentation par défaut permet au code non fiable d'accéder aux groupes de threads non root).

La sécurité Java vous permet d'empêcher l'accès au système de fichiers.

Pour les restrictions de base de données, vous pourrez peut-être utiliser la sécurité utilisateur SQL standard, mais celle-ci est assez faible. Sinon, vous devez fournir une API qui applique vos restrictions.

Éditer: Je dois signaler que la version de Rhino fournie avec JDK6 a déjà fait l'objet d'un travail de sécurité, mais n'inclut pas le compilateur.

Autres conseils

Pour vous protéger contre les boucles infinies, vous pouvez observer le nombre d'instructions pendant l'exécution du script (cela ne fonctionne qu'avec les scripts interprétés, pas avec les scripts compilés).

Il existe cet exemple dans Rhino JavaDocs pour empêcher un script de s'exécuter pendant plus de dix secondes:

 protected void observeInstructionCount(Context cx, int instructionCount)
 {
     MyContext mcx = (MyContext)cx;
     long currentTime = System.currentTimeMillis();
     if (currentTime - mcx.startTime > 10*1000) {
         // More then 10 seconds from Context creation time:
         // it is time to stop the script.
         // Throw Error instance to ensure that script will never
         // get control back through catch or finally.
         throw new Error();
     }
 }

Pour bloquer l'accès aux classes et méthodes Java, consultez ...

http://codeutopia.net/blog/2009 / 01/02 / sandboxing-rhino-in-java /

Je viens de tomber sur ce blog qui semble être utile pour le sandboxing, plus ou moins (rien que Rhino):

http://calumleslie.blogspot.com/2008/06/ simple-jvm-sandboxing.html

Si vous recherchez uniquement des fonctions JavaScript pures, voici une solution basée sur la bibliothèque intégrée Rhino dans le JDK sans importer de bibliothèques tierces:

  1. Découvrez le nom de classe de la fabrique de moteur de script JavaScript à l'aide de ScriptEngineManager # getEngineFactories
  2. Charger la classe de fabrique de moteur de script dans un nouveau chargeur de classes, dans lequel les JavaMembers ou autres classes associées seront ignorés.
  3. Appelez #getScriptEngine sur la fabrique de moteur de script chargée et les scripts eval sur le moteur de script renvoyé.

Si le script donné contient un script Java, le chargeur de classes essaiera de charger JavaMembers ou d'autres classes et déclenchera des exceptions de classe non trouvée. De cette manière, les scripts malveillants seront ignorés sans exécution.

Veuillez lire les fichiers ConfigJSParser.java et ConfigJSClassLoader.java pour plus de détails:

https://github.com/webuzz/simpleconfig/ arbre / maître / src / im / webuzz / config

Javascript est à thread unique et ne peut pas accéder au système de fichiers, je ne pense donc pas que vous ayez à vous en préoccuper. Je ne sais pas s'il existe un moyen de définir un délai d'expiration pour se prémunir contre des boucles infinies, mais vous pouvez toujours créer un thread (Java) qui exécute le script, puis le tuer après tant de temps.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top