Maison >Opération et maintenance >Sécurité >Quel est le mécanisme de sandbox de sécurité pour les applications Java ?
Si vous lisez souvent le code source, vous constaterez qu'il y a un morceau de code similaire au suivant dans le code source Java
<code class="hljs java">class File {<br> // 判断一个磁盘文件是否存在<br> public boolean exists() {<br> SecurityManager security = System.getSecurityManager();<br> if (security != null) {<br> security.checkRead(path);<br> }<br> ...<br> }<br>}<br></code>
Il s'agit évidemment d'un code de contrôle de sécurité. Il vérifie si vous avez l'autorisation d'accéder au. chemin du disque.Pourquoi le langage Java Quel type de code de contrôle de sécurité est-il nécessaire ? Regardons le code source de la fonction de connexion du socket client. Il doit vérifier si l'utilisateur a l'autorisation de se connecter à une certaine adresse réseau
<code class="hljs cs">class Socket {<br> public void connect(SocketAddress endpoint, int timeout) {<br> ...<br> SecurityManager security = System.getSecurityManager();<br> if (security != null) {<br> if (epoint.isUnresolved())<br> security.checkConnect(epoint.getHostName(), port);<br> else<br> security.checkConnect(addr.getHostAddress(), port);<br> }<br> }<br> ...<br> }<br>}<br></code>
Regardez le code source du socket serveur, il vérifiera le code source de la fonction de connexion du socket client. autorisation d'écoute du port
<code class="hljs cs">class ServerSocket {<br> public void bind(SocketAddress endpoint, int backlog) {<br> ...<br> SecurityManager security = System.getSecurityManager();<br> if (security != null)<br> security.checkListen(epoint.getPort());<br> ...<br> }<br>}<br></code>
Il semble que tous les appels de méthode liés aux opérations IO nécessitent des contrôles de sécurité. Il semble que les contrôles d'autorisation liés aux opérations d'E/S soient compréhensibles et que les processus utilisateur ne puissent pas accéder à volonté à toutes les ressources d'E/S. Mais même les variables d'environnement ne sont pas autorisées à être lues à volonté, et la restriction ne concerne pas toutes les variables d'environnement, mais une variable d'environnement spécifique. Ce contrôle de sécurité est-il un peu trop important ?
<code class="hljs cs">class System {<br> public static String getenv(String name) {<br> SecurityManager sm = getSecurityManager();<br> if (sm != null) {<br> sm.checkPermission(new RuntimePermission("getenv."+name));<br> }<br> return ProcessEnvironment.getenv(name);<br> }<br>}<br></code>
C'est parce que le gestionnaire de contrôle de sécurité de Java et la vérification des autorisations du système d'exploitation ne sont pas le même concept. Java écrit non seulement des applications côté serveur, il peut également s'exécuter sur le navigateur (Applet) en tant que client. sur un téléphone mobile (J2ME) sous la forme d'une application, les JVM utiliseront différentes stratégies de sécurité pour différentes plates-formes. Habituellement, les restrictions sur les applets sont très strictes et les applets ne sont généralement pas autorisés à exploiter des fichiers locaux. Avant d'effectuer des opérations d'E/S spécifiques, une fois le contrôle de sécurité de Java réussi, le système d'exploitation effectuera toujours une vérification des autorisations.
Nous n'ouvrons généralement pas le vérificateur de sécurité par défaut lors de l'exécution de programmes Java localement. Nous devons exécuter le paramètre jvm pour l'ouvrir
<code class="hljs shell">$ java -Djava.security.manager xxx<br>$ java -Djava.security.manager -DDjava.security.policy="${policypath}"<br></code>
Les restrictions de sécurité pouvant être personnalisées, vous devez également fournir un fichier de politique de sécurité spécifique. path. Par défaut Le chemin du fichier de stratégie est JAVA_HOME/jre/lib/security/java.policy Jetons un coup d'œil à ce qui est écrit dans ce fichier
<code class="hljs dart">// 内置扩展库授权规则<br>// 表示 JAVA_HOME/jre/lib/ext/ 目录下的类库可以全权访问任意资源<br>// 包含 javax.swing.*, javax.xml.*, javax.crypto.* 等等<br>grant codeBase "file:${{java.ext.dirs}}/*" {<br> permission java.security.AllPermission;<br>};<br><br>// 其它类库授权规则<br>grant {<br> // 允许线程调用自己的 stop 方法自杀<br> permission java.lang.RuntimePermission "stopThread";<br> // 允许程序监听 localhost 的随机可用端口,不允许随意订制端口<br> permission java.net.SocketPermission "localhost:0", "listen";<br> // 限制获取系统属性,下面一系列的配置都是只允许读部分内置属性<br> permission java.util.PropertyPermission "java.version", "read";<br> permission java.util.PropertyPermission "java.vendor", "read";<br> permission java.util.PropertyPermission "java.vendor.url", "read";<br> permission java.util.PropertyPermission "java.class.version", "read";<br> permission java.util.PropertyPermission "os.name", "read";<br> permission java.util.PropertyPermission "os.version", "read";<br> permission java.util.PropertyPermission "os.arch", "read";<br> permission java.util.PropertyPermission "file.separator", "read";<br> permission java.util.PropertyPermission "path.separator", "read";<br> permission java.util.PropertyPermission "line.separator", "read";<br> permission java.util.PropertyPermission "java.specification.version", "read";<br> permission java.util.PropertyPermission "java.specification.vendor", "read";<br> permission java.util.PropertyPermission "java.specification.name", "read";<br> permission java.util.PropertyPermission "java.vm.specification.version", "read";<br> permission java.util.PropertyPermission "java.vm.specification.vendor", "read";<br> permission java.util.PropertyPermission "java.vm.specification.name", "read";<br> permission java.util.PropertyPermission "java.vm.version", "read";<br> permission java.util.PropertyPermission "java.vm.vendor", "read";<br> permission java.util.PropertyPermission "java.vm.name", "read";<br>};<br></code>
grant Si le paramètre codeBase est fourni, les autorisations sont configurées pour le. bibliothèque de classes spécifique. Les règles, si aucun codeBase n'est spécifié, sont les règles configurées pour toutes les autres bibliothèques.
Si le contrôle de sécurité échoue, une exception java.security.AccessControlException sera levée. Même si le contrôle de sécurité réussit, le contrôle des autorisations du système d'exploitation peut échouer, auquel cas d'autres types d'exceptions seront générés.
Si vous suivez les règles configurées ci-dessus, la JVM utilisant la politique de sécurité par défaut ne pourra pas accéder aux fichiers locaux car les règles d'autorisation utilisent une liste blanche. Si vous avez besoin d'accéder aux fichiers locaux, vous pouvez ajouter les règles suivantes
<code class="hljs lua">permission java.io.FilePermission "/etc/passwd", "read";<br>permission java.io.FilePermission "/etc/shadow", "read,write";<br>permission java.io.FilePermission "/xyz", "read,write,delete";<br>// 允许读所有文件<br>permission java.io.FilePermission "*", "read";<br></code>
Les paramètres de configuration des autorisations correspondent exactement à ses paramètres de constructeur
<code class="hljs java">public FilePermission(String path, String actions) {<br> super(path);<br> init(getMask(actions));<br>}<br></code>
Les règles de sécurité par défaut de Java sont divisées en plusieurs modules principaux, chaque module a ses propres paramètres de configuration
où AllPermission signifie ouvrir toutes les autorisations. Il existe également un invité non invité, HibernatePermission, qui n'est pas un module d'autorisation intégré. Il est personnalisé par le framework Hibernate, ce qui signifie que les règles de sécurité prennent en charge les extensions personnalisées. Pour étendre, c'est simple, il suffit d'écrire une sous-classe Permission et d'implémenter ses quatre méthodes abstraites.
<code class="hljs java">abstract class Permission {<br> // 权限名称,对于文件来说就是文件名,对于套接字来说就是套接字地址<br> // 它的意义是子类可定制的<br> private String name;<br> // 当前权限对象是否隐含了 other 权限<br> // 比如 AllPermission 的这个方法总是返回 true<br> public abstract boolean implies(Permission other);<br> // equals 和 hashcode 用于权限比较<br> public abstract boolean equals(Object obj);<br> public abstract int hashCode();<br> // 权限选项 read,write,xxx<br> public abstract String getActions();<br>}<br><br>class CustomPermission extends Permission {<br> private String actions;<br> CustomPermission(string name, string actions) {<br> super(name)<br> this.actions = actions;<br> }<br> ...<br>}<br></code>
Lorsque la JVM est démarrée, les règles d'autorisation définies dans le profil seront chargées dans le pool d'autorisations. Le programme utilisateur utilise le pool d'autorisations dans une méthode API spécifique pour déterminer s'il contient l'autorisation d'appeler cette API, et sera finalement implémenté dans le pool d'autorisations appelant. La méthode implique de chaque objet d'autorisation est utilisée pour déterminer s'il dispose de l'autorisation spécifiée.
<code class="hljs cs">class CustomAPI {<br> public void someMethod() {<br> SecurityManager sec = System.getSecurityManager();<br> if(sec != null) {<br> sec.CheckPermission(new CustomPermission("xname", "xactions"));<br> }<br> ...<br> }<br>}<br></code>
L'activation du contrôle de sécurité réduira l'efficacité d'exécution du programme. S'il y a trop de règles d'autorisation définies dans le profil, l'efficacité du contrôle sera très lente. Lors de son utilisation, faites attention au contrôle de sécurité et utilisez-le avec parcimonie. .
Il existe de nombreux points de contrôle de sécurité dans le bac à sable. Certains scénarios courants sont répertoriés ci-dessous
Opérations sur les fichiers
Opérations sur les sockets
Threads et groupes de threads
Contrôle du chargeur de classe
Contrôle de la réflexion
Acquisition d'informations sur la pile de threads
Contrôle du proxy réseau
Contrôle de lecture et d'écriture des cookies
Si les contrôles de sécurité de votre programme serveur sont activés, vous devez en ouvrir un grand nombre dans la configuration de la politique. Les paramètres de sécurité des fichiers sont très fastidieux et s'il y a trop de configurations, les performances de la vérification subiront également une certaine perte. Ceci est quelque peu similaire aux paramètres d'autorisation des applications Android. Une série de sous-autorisations d'application doivent être répertoriées dans le fichier de configuration de chaque application Android. Cependant, il semble qu'il ne soit pas nécessaire d'activer des contrôles de sécurité lors de l'écriture de programmes côté serveur en Java.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!