Bonjour,
JE pense que tu prends un très très grand risque, beaucoup trop grand, si tu exécutes du code sans l'avoir vérifié manuellement auparavant. A mon avis la vérification manuelle est le meilleur rempart contre les hackers en herbe qui ne mettront pas long à déferler et à s'en donner au max pour tout te casser.
Les VM, c'est bien, mais c'est quand même très très lourd à mettre en place, et c'est même pas 100% isolant (il existe des virus qui arrivent à se propager chez l'hôte, ça s'est déjà vu sous windows en tout cas).
JE dirais donc simplement, oublie l'exécution automatique de code sans vérification humaine; c'est beaucoup trop dangereux.
Suivant le langage et l'environnement visé, sans être obligé d'aller jusqu'à la VM, il y a moyen d'interdire tout ou en partie l'accès à la bibliothèque standard et donc aux accès habituels (disque, réseau, etc.). IL peut s'agir d'écraser des variables globales fournies de base, ou d'empêcher l'importation de modules non désirés. Par exemple en python on peut commencer par bloquer l'importation des modules io et os, et puis la fonction open.... Mais tu vois bien que ça s'avère vite problématique et, au demeurant, contournable quand même, il suffit d'un seul oubli, une seule possibilité à laquelle tu n'as pas pensé, une seule petite astuce et paf.
En lua il y a moyen avec les environnements de fonction d'isoler complètement un bout de code. Mais c'est lua, problablement un des langages de script le plus simple, si pas LE plus simple.
En PHP on a tellement de possibilités d'interaction avec l'extérieur qu'il vaut mieux oublier, quand bien même on a DISABLE_FUNCTIONS et DISABLE_CLASSES dans le php.ini.
ET Java, bonne chance pour te faire un rt.jar customisé.
ET tout ça, au final, pour quoi ? pour voir s'affronter des IA au pierre-papier-ciseaux ou une variante du jeu du prisonnier ? Franchement ça n'en vaut pas la peine. Vérifie systématiquement les codes envoyés avant leur exécution, tu éviteras bien des sueurs froides.