web-dev-qa-db-fra.com

Quelle mesure de sécurité doit-on mettre en œuvre avant d'exécuter les fichiers téléchargés par l'utilisateur?

Je veux faire un petit casse-tête de programmation sur mon site Web. Il va y avoir une tâche. L'utilisateur sera invité à télécharger un fichier source C++ avec sa solution. Le fichier doit être compilé, exécuté avec une entrée et vérifié s'il produit une sortie correcte. Quels sont les risques de sécurité? Comment puis-je m'assurer que le fichier téléchargé ne pourra rien faire de malveillant?

Alternativement, il existe des sites comme Tutorials Point qui vous permettent de compiler et d'exécuter du code C++. Comment gèrent-ils la sécurité?

40
Jen

Il est impossible d'analyser un programme pour savoir s'il fera quelque chose de malveillant. Cela est vrai que vous tentiez d'analyser le code source ou compilé.

La façon de faire ce que vous demandez se fait en compilant et en exécutant le code dans un bac à sable. Une fois le programme terminé (ou après un délai d'attente que vous avez décidé), vous détruisez le bac à sable.

La sécurité d'une telle construction est aussi sûre que le bac à sable que vous utilisez. Selon les exigences du code dont vous avez besoin pour exécuter le bac à sable, cela peut être quelque chose de simple comme le mode informatique sécurisé Linux, ou quelque chose de compliqué comme une machine virtuelle complète - idéalement sans connectivité réseau.

Plus le bac à sable est compliqué, plus le risque de vulnérabilité de sécurité dans le bac à sable compromet une conception par ailleurs bonne.

Certaines langues peuvent être compilées en toute sécurité en dehors d'un bac à sable. Mais il existe des langues où même les compiler peut consommer une quantité imprévisible de ressources. Cette question sur un site frère montre quelques exemples de la façon dont un petit code source peut exploser en une grande sortie.

Si le compilateur lui-même est exempt de vulnérabilités, il peut être suffisant de fixer des limites sur la quantité de CPU, de mémoire et d'espace disque qu'il est autorisé à consommer. Pour une meilleure sécurité, vous pouvez exécuter le compilateur à l'intérieur d'une machine virtuelle.

Évidemment, ces méthodes peuvent être combinées pour une couche de sécurité supplémentaire. Si je devais construire un tel système, je démarrerais probablement une machine virtuelle et à l'intérieur de la machine virtuelle, j'utiliserais ulimit pour limiter l'utilisation des ressources du compilateur. Ensuite, je lierais le code compilé dans un wrapper pour l'exécuter en mode informatique sécurisé. Enfin, toujours à l'intérieur de la machine virtuelle, j'exécutais l'exécutable lié.

53
kasperd

C'est un problème vraiment difficile, et un problème que tous les juges de code en ligne doivent résoudre. Fondamentalement, vous demandez comment vous pouvez empêcher quelqu'un qui peut exécuter du code arbitraire sur votre machine de le reprendre.

J'ai codé sur un juge en ligne ( Kattis ) pendant une dizaine d'années, et voici quelques-unes de mes expériences de construction de solutions de sécurité pour ce type de scénario:

  1. Les premières versions étaient basées sur une prison Solaris. Il s'avère que vous pouvez causer beaucoup de ravages dans une prison, et cela ne vous donne pas la granularité dont vous avez besoin.
  2. Nous avons implémenté une solution de filtrage des appels système à l'aide de ptrace. Cela introduit un très gros (plusieurs changements de contexte) sur les appels système et garder le profil de sécurité synchronisé lorsque les compilateurs et les coureurs changent est un cauchemar. Le dernier clou dans le cercueil pour cette solution était le filetage. Si vous autorisez le thread, une application peut utiliser un thread pour réécrire l'appel système entre l'inspection et l'exécution, et par exemple Java nécessite un thread.
  3. De nos jours, nous utilisons une combinaison de groupes de contrôle et d'espaces de noms. Cela donne une surcharge étonnamment faible, et comme elles font partie des primitives de sécurité dans le noyau Linux, elles sont robustes. Jetez un oeil à MOE Isolate pour une idée de la façon dont cela peut être fait. Isoler résout très probablement votre problème.

Notez que bien que les conteneurs, tels que les dockers ou les machines virtuelles, soient populaires, ils peuvent ne pas être le meilleur choix pour une solution de sécurité dans ce type de scénario. Il est difficile d'obtenir le contrôle fin et la surveillance des ressources que vous souhaitez probablement, il est difficile d'empêcher un processus malveillant de se détériorer à l'intérieur de votre conteneur et, le démarrage et la destruction des conteneurs ont beaucoup de frais généraux.

28
pehrs

Dans le cas particulier d'un site de puzzle, envisagez l'alternative: ne vous embêtez pas. Demandez aux participants de télécharger la sortie afin de ne pas avoir à exécuter de code non approuvé. Cela vous permet d'économiser de la puissance de calcul, d'éviter un risque de sécurité et de permettre aux gens de rivaliser dans n'importe quelle langue. S'il y a un prix en jeu, vous pouvez vérifier manuellement l'entrée gagnante ultérieurement.

Si la forme de votre puzzle le permet, vous pouvez contrecarrer les solutions de copier-coller en générant des entrées aléatoires et en écrivant un vérificateur. Voici comment fonctionne Google Code Jam. Voir https://code.google.com/codejam/problem-preparation.html#iogen

7
Colonel Panic