2010-12-01 21 views
9

Actuellement, j'essaie d'écrire le Sandbox pour exécuter du code Java non approuvé. L'idée est d'isoler l'application Java de l'accès au système de fichiers ou aux sockets réseau. La solution que j'ai actuellement est réécrite SecurityManager, qui interdit tout accès à IO ou au réseau.Bac à sable Java. Utilisation de SecurityManager pour rediriger l'accès aux E/S

Maintenant, je veux pas interdire, mais de rediriger les appels vers le système de fichiers, à savoir si l'application veut écrire « /home/user/application.txt » doit être remplacé le chemin vers le fichier avec quelque chose comme "/temp/trusted_folder/application.txt". Donc, fondamentalement, je veux permettre aux applications d'accéder au système de fichiers uniquement dans un dossier particulier et de rediriger tous les autres appels vers ce dossier.

Donc, voici la méthode de la classe FileOutputStream, où SM est demandé, s'il existe une autorisation d'écrire dans le chemin donné.

public FileOutputStream(File file, boolean append) 
    throws FileNotFoundException 
{ 
    String name = (file != null ? file.getPath() : null); 
    SecurityManager security = System.getSecurityManager(); 
    if (security != null) { 
     security.checkWrite(name); 
    } 
    if (name == null) { 
     throw new NullPointerException(); 
    } 
    fd = new FileDescriptor(); 
    fd.incrementAndGetUseCount(); 
    this.append = append; 
    if (append) { 
     openAppend(name); 
    } else { 
     open(name); 
    } 
} 

De toute évidence, le SM ne dispose pas d'un accès à FileOutputStream et ne peut pas modifier les variables internes dans la méthode (comme nom ou fichier) ou affecter en quelque sorte l'ordre d'exécution, à l'exception de lancer la SecurityException. Je comprends, qu'accéder aux champs internes est une violation des principes orientés objet, je comprends, que les variables locales sont visibles et n'existent qu'à l'intérieur de la méthode, là où elles ont été déclarées. Donc, ma question est la suivante: Existe-t-il des moyens de permettre à Security Manager de remplacer les appels au système de fichiers? Sinon, y a-t-il d'autres approches que je peux utiliser pour faire cela?

J'espère que j'étais assez clair.

Répondre

6

SecurityManager ne peut pas faire cela, il peut seulement dire oui ou non.

Je peux penser à deux options:

  1. Faites quelque chose au niveau du système d'exploitation avec le système de fichiers. Il y a des choses comme chroot jails. Ce serait transparent pour l'application, mais nécessite un travail en dehors de Java.

  2. Fournissez une API à l'application qui ouvre le FileOutputStream pour eux. La couche API peut décider d'où proviennent les fichiers et elle est privilégiée (dans les termes de Security Manager) pour ouvrir les fichiers de n'importe où. Bien sûr, cela nécessite que l'application sandbox utilise votre API au lieu de java.io.File directement. Mais il est également beaucoup plus flexible, et à un moment donné, il est probablement nécessaire qu'une application soit consciente du sandbox et utilise l'API sandbox, comme sur Java WebStart for example.

+0

merci pour la réponse. La première option que je ne pouvais pas accepter, puisque je ne veux pas me limiter à un seul système d'exploitation, mais la deuxième option semble plutôt sympa. J'ai cherché un remplacement de l'API et j'ai découvert que l'outil JMockit peut mocker des classes et faire des stubs. Donc, fondamentalement, je vais y réfléchir et je pense que c'est ce dont j'ai besoin maintenant. – Sevich

0

Je ne pense pas que cela puisse être fait. Le gestionnaire de sécurité est conçu pour refuser l'accès à des opérations spécifiques, et non pour rediriger des opérations d'E/S ou effectuer d'autres opérations de ce type.

même si cela est possible grâce à un piratage de reflet sérieux, il ne sera probablement pas portable entre différents fournisseurs jvm et même différents systèmes d'exploitation exécutant le même jvm. (c'est parce que vous aurez besoin de manipuler des classes spécifiques au système d'exploitation). Ce que vous voulez faire devrait être tenté à un niveau inférieur, voir chroot pour linux et d'autres techniques de virtualisation plus lourdes.

5

Maintenant que Java est open source, vous pouvez télécharger le code source à FileOutputStream, modifier son code source de faire appliquer les contraintes que vous le souhaitez, le recompiler, l'ajouter à un pot, et préfixer que JAR bootloader classpath de la machine virtuelle Java:

java -Xbootclasspath/p:myModifiedJavaClasses.jar sandbox.Main -run untrusted.Main 

la machine virtuelle Java va maintenant utiliser votre implémentation de java.io.FileOutputStream au lieu de l'habituel. Rincez et répétez pour toutes les classes JSE qui nécessitent une logique de redirection sandbox spéciale.

Ce n'est pas la solution la plus portable ou la plus facile à déployer, car elle nécessite des modifications «en dehors de la VM» pour lancer les paramètres, mais dans certaines situations cette solution peut être acceptable et efficace.