Comment exécuter des serveurs de code non approuvés?

J'essaie d'exécuter un code javascript non-sécurisé dans linux + node.js avec le module sandbox, mais il est brisé, tout ce dont j'ai besoin est de permettre aux utilisateurs d'écrire des programmes javascript qui impriment du texte. Aucun autre i / o n'est autorisé et il faut simplement utiliser javascript, pas d'autres modules de noeud. Si ce n'est pas vraiment possible, quelle autre langue proposez-vous pour ce type de tâche? Le jeu de fonctionnalités minimal dont j'ai besoin est le calcul des mathématiques, des réggex, des manipulations de chaînes et des fonctions JSON de base. Les scripts se disputeront, disons 5 secondes, et le processus sera tué, comment puis-je réaliser cela?

J'ai récemment créé une bibliothèque pour la suppression du code non approuvé, il semble correspondre aux exigences (exécute un code dans un processus restreint dans le cas de Node.js et dans un Worker dans un iframe en calque pour un navigateur):

https://github.com/asvd/jailed

Il existe une possibilité d'exporter l'ensemble de méthodes donné de l'application principale dans le bac à sable, ce qui fournit une API personnalisée et un ensemble de privilèges (cette fonctionnalité était en fait la raison pour laquelle j'ai décidé de créer une bibliothèque à partir de zéro). Les mathématiques, les regexp et les questions liées aux chaînes sont fournis par le JavaScript lui-même, tout ce qui peut être explicitement exporté de l'extérieur (comme une fonction pour communiquer avec l'application principale).

L'idée de base des bac à sable est que vous avez besoin de variables prédéfinies comme globals pour faire des choses, donc si vous leur refusez un script en les désactivant ou en les remplaçant par un contrôle, il ne peut pas échapper. Tant que vous n'oubliez rien.

Tout d'abord remplacer le refus doit () ou le remplacer par quelque chose de contrôlé. N'oubliez pas le processus et la «racine» mondiale, la chose difficile n'est pas d'oublier tout, c'est pourquoi il est bon de compter sur quelqu'un d'autre ayant construit un bac à sable 😉

Docker.io C'est un nouvel enfant génial sur le bloc, qui utilise LXC s et CGroups pour créer des sandbox.

Voici une implémentation d'un gist en ligne (similaire à codepad.org ) à l'aide de Docker et Go Lang

Cela permet simplement de démontrer que l'on peut exécuter en toute sécurité un code non approuvé écrit dans de nombreux langages de programmation dans Docker Containers , y compris node.js

Posez-vous ces questions:

  1. Êtes-vous l'une des personnes les plus intelligentes de la planète?
  2. Bénéficiez-vous régulièrement des offres d'emploi par Google, Mozilla et Kaspersky Lab, car cela vous ennuierait?
  3. Est-ce que le «code non approuvé» provient de personnes travaillant dans la même entreprise que vous ou de criminels et d'enfants d'ordinateurs ennuyés partout dans le monde?
  4. Êtes-vous sûr que node.js n'a pas de trous de sécurité qui pourraient glisser dans votre bac à sable?
  5. Pouvez-vous écrire un code 100% sans erreur parfait?
  6. Savez-vous tout sur JavaScript?

Comme vous le savez déjà par vos expériences avec le module sandbox , écrire votre propre bac à sable n'est pas trivial. Le principal problème avec les sandbox est que vous devez tout bien. Une erreur va ruiner complètement votre sécurité, c'est pourquoi les développeurs de navigateurs se battent constamment avec des biscuits partout dans le monde.

Cela dit, les bacs à sable simples sont assez faciles à faire. Tout d'abord, vous devrez écrire votre propre interpréteur JavaScript parce que vous ne pouvez pas utiliser celui de node.js à cause de eval() et require() (les deux permettraient aux crackers d'échapper à votre sandbox).

L'interprète doit s'assurer que le code interprété ne peut accéder à rien en plus des quelques symboles globaux que vous fournissez. Cela signifie qu'il ne peut pas y avoir une fonction eval() , par exemple (ou vous devez vous assurer que cette fonction n'est évaluée que dans le cadre de votre propre interpréteur JavaScript).

Inconvénient cette approche: beaucoup de travail et si vous faites une erreur dans votre interprète, les craquelins peuvent quitter le bac à sable.

Une autre approche est de nettoyer le code et de l'exécuter avec node.js's eval() . Vous pouvez nettoyer le code existant en exécutant un groupe de regexp sur le dessus, comme /eval\s*[(]//g pour supprimer les parties de code malveillant.

Inconvénient cette approche: il est facile de faire une erreur qui vous laissera vulnérable à une attaque. Par exemple, il pourrait y avoir une inadéquation entre ce que regexp et ce que node.js considère comme "espace blanc". Un espace blanc unicode obscur pourrait être accepté par l'interprète mais pas par regexp qui permettrait à un attaquant d'exécuter eval() .

Ma suggestion: écrivez un petit étui de démonstration qui montre comment le module de sandbox est cassé et qu'il soit réparé. Cela vous permettra d'économiser beaucoup de temps et d'efforts et s'il y a un bug dans le bac à sable, ce ne sera pas votre faute (enfin, pas tout au moins).

Si vous pouvez vous occuper de la performance, vous pouvez exécuter le JS dans une machine virtuelle jetée avec les limites de CPU et de mémoire appropriées.

Bien sûr, alors vous faites confiance à la sécurité de la solution VM. En l'utilisant avec un bac à sable JS ordinaire, vous disposez de deux couches de sécurité.

Pour une couche supplémentaire, placez le bac à sable sur une machine physique différente de celle de votre application principale.

Je suis confronté à un problème similaire en ce moment et je ne lis que de mauvaises choses sur le module sandbox.

Si vous n'avez pas besoin de quelque chose de spécifique à l'environnement du nœud, je pense que la meilleure approche sera d'utiliser un navigateur sans tête tel que PhantomJS ou Chimera à utiliser comme environnement de sandbox.

Sachez qu'il est assez tard pour répondre à la question, supposons que l'outil ci-dessous pourrait être une valeur ajoutée qui n'est pas mentionnée dans les réponses / commentaires ci-dessus.

Essayer d'implémenter un cas d'utilisation similaire. Après avoir parcouru les ressources Web, https://www.npmjs.com/package/vm2 semble bien gérer l'environnement sandbox (nodejs).

C'est à peu près satisfait les fonctionnalités de sandboxing, comme la restriction de l'accès aux modules internes ou externes, les échanges de données entre sandbox, etc.