2008-10-03 8 views
13

Je veux être en mesure d'exécuter du code Ruby non filtré. Je veux être en mesure de transmettre des variables au code non fiable qu'il peut utiliser. Je veux aussi que le code me renvoie un résultat. Voici un exemple conceptuel de ce que je penseComment exécuter du code Ruby non sécurisé dans un bac à sable sécurisé?

input = "sweet" 
output = nil 
Thread.start { 
    $SAFE = 4 
    #... untrusted code goes here, it uses the input variable(s) 
    #to calculate some result that it places in the output variable 
} 
#parse the output variable as a string. 

Juste pour clarifier, j'utilise essentiellement le code non sécurisé en fonction. Je veux fournir ses quelques entrées, puis lui permettre d'écrire à la sortie. C'est tout ce que je veux vraiment, je ne m'inquiète pas comment c'est fait, je veux juste la possibilité d'utiliser le code Ruby non fiable comme une sorte de fonction. La solution ne doit pas ressembler au code que j'ai écrit plus haut, je l'utilise juste pour illustrer ce que je veux.

Maintenant, je peux penser actuellement 3 façons de le faire:

  1. Utilisez la construction de niveau de sécurité de $ ci-dessus.
  2. whytheluckystiff a un plugin Sandbox pour ruby ​​
  3. Je pourrais exécuter chaque fonction dans sa propre machine virtuelle, en utilisant une sorte de logiciel de virtualisation comme vmware ou Xen ou quelque chose.

Je me demande si quelqu'un a des recommandations pour exécuter le code ruby ​​non approuvé d'une manière fonctionnelle? Quelle option recommanderiez-vous? Comment vous y prendrez-vous? Merci.

Répondre

12

$ SAFE n'est pas suffisant; vous devez être au moins au niveau du bac à sable bizarre de Why. Cependant, je ne sais pas si ce code de bac à sable est activement maintenu ou s'il a jamais résolu les trous tels que des boucles infinies, etc.

Négatif signifie généralement hostile. Si vous pouvez vous détendre d'hostile à, disons, «naïf», et en fonction des exigences de votre application, vous pourriez sortir avec sandboxing dans Ruby. Ce n'est pas vraiment un scénario de première classe dans la conception du langage.

Même avec cela, vous n'avez probablement pas besoin d'aller au niveau de séparation de la machine. Je me sentirais en sécurité en utilisant un bac à sable dans un processus généré séparément, avec votre application fonctionnant comme un gestionnaire de processus pour tuer ceux qui parviennent à se bloquer/flamber. Maintenant, c'est un peu plus de travail que votre simple bloc ci-dessus. Mais rappelez-vous et continuez à répéter, "SAFE ne peut pas faire face à hostile".

+3

Est-ce que quelqu'un a des références qui expliquent ce qui ne va pas avec $ SAFE? – sheldonh

3

Je recommande fortement d'utiliser simplement JRuby.

La JVM dispose d'un modèle de sécurité très solide depuis le début, et JRuby s'en est remis. Vous pouvez restreindre l'accès aux fichiers, restreindre le chargement du code, et bien plus encore. C'est lointain mieux que tout ce qui existe dans implicite Ruby impls, et il y a un certain nombre de sites qui exécutent sandboxed, les sites accessibles aux utilisateurs sur JRuby exactement dans ce but.

+0

+1, mais pour l'anecdote, JRuby n'implémente pas complètement '$ SAFE', n'est-ce pas? –

+0

Non, nous ne le faisons pas, surtout parce que les vérifications doivent être tracées partout dans le code, et il n'y a presque aucun moyen de prouver que vous avez tout couvert. Je voudrais redéfinir les niveaux SAFE en termes de politiques de sécurité JVM, puisque nous n'aurions pas de vérifications manuelles à appliquer alors. –

3

$SAFE ne vous protège pas contre tout ce qu'un pirate malveillant pourrait faire. Après avoir suivi cette voie (voir Ruby: creating a sandboxed eval?), j'ai suivi les avis avisés des commentateurs et intégré un interpréteur spécifique à l'application qui m'a donné un contrôle complet sur ce qui pouvait et ne pouvait pas être fait (voir Ruby: looking for ruby-embeddable interpreter or scripting language).

Il est avéré être incroyablement facile en utilisant stickup (comme moins d'une heure de télécharger le petit bijou à un interprète sur mesure) - voir https://github.com/jcoglan/stickup

1

J'ai créé un bijou appelé « sandbox de confiance » qui exécute le code Ruby dans un conteneur Docker entièrement contrôlé. Vous pouvez désactiver le réseau, définir des quotas de disque, limiter le temps d'exécution, équilibrer le processeur avec d'autres conteneurs en cours d'exécution, définir des limites de mémoire, etc. Et le temps système est relativement faible.

Vous pouvez en lire davantage ici: https://github.com/vaharoni/trusted-sandbox

Laissez-moi savoir ce que vous pensez!

Questions connexes