Heim > Artikel > Betrieb und Instandhaltung > Was ist der Sicherheits-Sandbox-Mechanismus für Java-Anwendungen?
Wenn Sie den Quellcode häufig lesen, werden Sie feststellen, dass sich im Java-Quellcode ein Code befindet, der dem folgenden ähnelt:
<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>
Es handelt sich offensichtlich um einen Sicherheitsüberprüfungscode Festplattenpfad. Warum benötigt die Java-Sprache welche Art von Sicherheitsüberprüfungscode? Schauen wir uns den Quellcode der Verbindungsfunktion des Client-Sockets an. Es muss überprüft werden, ob der Benutzer die Berechtigung hat, eine Verbindung zu einer bestimmten Netzwerkadresse herzustellen Abhörberechtigung des Ports
<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>
Es scheint, dass alle Methodenaufrufe im Zusammenhang mit E/A-Vorgängen Sicherheitsüberprüfungen erfordern. Es scheint, dass die Berechtigungsprüfung im Zusammenhang mit E/A-Vorgängen verständlich ist und Benutzerprozesse nicht nach Belieben auf alle E/A-Ressourcen zugreifen können. Aber selbst Umgebungsvariablen dürfen nicht nach Belieben gelesen werden, und die Einschränkung gilt nicht für alle Umgebungsvariablen, sondern für eine bestimmte Umgebungsvariable. Ist diese Sicherheitsüberprüfung etwas zu viel?
<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>
Das liegt daran, dass der Sicherheitsüberprüfungsmanager von Java und die Berechtigungsprüfung des Betriebssystems nicht dasselbe Konzept sind. Java schreibt nicht nur serverseitige Anwendungen, sondern kann auch im Browser (Applet) ausgeführt werden auf einem Mobiltelefon (J2ME) in Form einer App verwenden unterschiedliche Sicherheitsstrategien für verschiedene Plattformen. Normalerweise sind die Einschränkungen für Applets sehr streng und Applets dürfen im Allgemeinen keine lokalen Dateien bedienen. Bevor bestimmte E/A-Vorgänge ausgeführt werden, führt das Betriebssystem nach bestandener Java-Sicherheitsprüfung immer noch eine Berechtigungsprüfung durch.
Normalerweise öffnen wir den Sicherheitsprüfer nicht standardmäßig, wenn wir Java-Programme lokal ausführen. Wir müssen den JVM-Parameter ausführen, um ihn zu öffnen
<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>
Da die Sicherheitsbeschränkungen angepasst werden können, müssen Sie auch eine bestimmte Sicherheitsrichtliniendatei bereitstellen Pfad. Standardmäßig ist der Pfad der Richtliniendatei JAVA_HOME/jre/lib/security/java.policy. Schauen wir uns an, was in dieser Datei geschrieben ist Spezifische Klassenbibliothek Die Regeln, wenn keine codeBase angegeben ist, sind die Regeln, die für alle anderen Bibliotheken konfiguriert sind.
Wenn die Sicherheitsüberprüfung fehlschlägt, wird eine java.security.AccessControlException-Ausnahme ausgelöst. Selbst wenn die Sicherheitsüberprüfung erfolgreich ist, schlägt die Berechtigungsüberprüfung des Betriebssystems möglicherweise fehl. In diesem Fall werden andere Arten von Ausnahmen ausgelöst.
<code class="hljs shell">$ java -Djava.security.manager xxx<br>$ java -Djava.security.manager -DDjava.security.policy="${policypath}"<br></code>
<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>
Java-Standardsicherheitsregeln sind in mehrere Hauptmodule unterteilt, jedes Modul hat seine eigenen Konfigurationsparameter
wobei AllPermission das Öffnen aller Berechtigungen bedeutet. Es gibt auch einen ungebetenen Gast, HibernatePermission, der kein integriertes Berechtigungsmodul ist. Er wird vom Hibernate-Framework angepasst, was bedeutet, dass Sicherheitsregeln benutzerdefinierte Erweiterungen unterstützen. Das Erweitern ist einfach: Schreiben Sie einfach eine Permission-Unterklasse und implementieren Sie deren vier abstrakte Methoden.
<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>
Wenn die JVM gestartet wird, werden die im Profil definierten Berechtigungsregeln in den Berechtigungspool geladen. Das Benutzerprogramm verwendet den Berechtigungspool in einer bestimmten API-Methode, um zu bestimmen, ob er die Berechtigung zum Aufrufen dieser API enthält wird schließlich in den aufrufenden Berechtigungspool implementiert. Die Methode „implices“ jedes Berechtigungsobjekts wird verwendet, um zu bestimmen, ob es über die angegebene Berechtigung verfügt.
<code class="hljs java">public FilePermission(String path, String actions) {<br> super(path);<br> init(getMask(actions));<br>}<br></code>
Die Aktivierung der Sicherheitsüberprüfung verringert die Ausführungseffizienz des Programms. Wenn im Profil zu viele Berechtigungsregeln definiert sind, ist die Überprüfungseffizienz sehr langsam. Achten Sie bei der Verwendung auf die Sicherheitsüberprüfung und gehen Sie sparsam damit um .
Es gibt viele Sicherheitskontrollpunkte in der Sandbox. Nachfolgend sind einige häufige Szenarien aufgeführt. Dateioperationen. Socket-Operationen. Threads und Thread-Gruppen
Reflexionskontrolle
Das obige ist der detaillierte Inhalt vonWas ist der Sicherheits-Sandbox-Mechanismus für Java-Anwendungen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!