Security
JOHANNES KEPLER UNIVERSITY LINZ
Research and teaching network
Pratikum SWE 2
© Institut für Systemsoftware, Johannes Kepler Universität Linz
Security
Einführung
Klassenlader
Sicherheitsmanager und Berechtigungen
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
2
Sicherheitsmechanismen in Java
Virtuelle Maschine
fehlerhafte Arrayzugriffe
fehlerhafte Casts
…
Klassenlader
Laden von Code
Byte-Code Verifikation
Sicherheitsmanager-Klassen
erlaubte und unerlaubte Operationen und Zugriffe
Verschlüsselungsmechanismen
Codesignierung
Authentifikation
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
3
Security
Einführung
Klassenlader
Sicherheitsmanager und Berechtigungen
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
4
Laden von Klassen
In Java wird Code inkrementell nach Bedarf geladen
Prozess des Ladens von Klassencode
(veranschaulicht anhand Ausführung des Programms MyProgram):
Laden des Codes in File MyProgram.class
Laden von allen Klassen von Variablen und Superklassen der Klasse
MyProgram
Ausführung der Methode main der Klasse MyProgram
Laden aller bei der Ausführung von main benötigten Klassen
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
5
Klassenlader
Das Laden von Klassen wird durch ClassLoader-Objekte durchgeführt
Zugriff auf ClassLoader
Class clazz = Class.forName(“MyProgram“);
ClassLoader loader = clazz.getClassLoader();
Standard ClassLoader!
ClassLoader loader = ClassLoader.getSystemClassLoader();
ClassLoader erlaubt
Klassen explizit zu laden
Class myClass = loader.loadClass("mypack.MyClass");
und zu definieren
byte[] classCode = ...;
loader.defineClass(“MyDefinedClass“, classCode, 0, classCode.length);
Setzen des Klassenladers
Für einen Thread kann man ContextClassLoader setzen
Thread thread = Thread.currentThread();
thread.setContextClassLoader(loader);
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
Damit werden alle Klassen für diesen
Thread mit eigenem Klassenlader geladen!
6
Arten von Klassenlader
Java verwendet unterschiedle Klassenlader
Bootstrap-Klassenlader:
lädt alle Systemklassen aus JAR-Datei rt.jar
Erweiterungsklassenlader:
lädt alle Erweiterungen aus Verzeichnis jre/lib/ext
Systemklassenlader (besser Anwendungsklassenlader):
lädt die Anwendungsklassen aus Klassenpfad (CLASSPATH)
Spezielle Klassenlader:
Anwendungsspezifisches Klassenlader als Spezialisierung der
Standardklassenlader
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
7
Hierarchie der Klassenlader
Klassenlader stehen in einer Über-/Untergeordnet-Beziehung zueinander
Hierarchie
zu oberst Bootstrap-Klassenlader
Bootstrapklassenlader
rt.jar
Erweiterungsklassenlader
jre/lib/ext
Systemklassenlader
CLASSPATH
Spezifischer
Klassenlader
spezifisch
dann Erweiterungsklassenlader
dann Systemklassenlader
Dann eventuell anwendungsspezifische
Klassenlader
Jeder Klassenlader delegiert Laden einer
Klasse an übergeordneten Klassenlader
und lädt die Klasse nur selber, wenn der
übergeordnete scheitert
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
8
Beispiel Spezifischer Klassenlader
Eigener Klassenlader als Intanz von URLClassLoader
Laden von Klassen aus Plugin-JAR
Plugin-JAR nicht
im CLASSPATH!
URL pluginUrl = new URL("file:c:/plugins.jar");
URLClassLoader pluginLoader = new URLClassLoader(
new URL[] { pluginUrl },
ClassLoader.getSystemClassLoader()
);
Class<?> cl = pluginLoader.loadClass("plugin1.PluginClass");
cl.getMethod("test").invoke(null);
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
übergeordnete
Klassenlader
9
Beispiel: Selbstimplementierter Klassenlader
Klassenlader als Spezialisierung von ClassLoader
Entschlüsselung von verschlüsselten ByteCode-Dateien
durch Überschreiben von Methode findClass
public class CryptoClassLoader extends ClassLoader {
private final String path;
private final int key;
public CryptoClassLoader(String path, int key) {...}Methode findClass wird von
loadClass aufgerufen!
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classBytes = null;
try {
classBytes = loadAndDecryptClassBytes(name);
} catch (IOException e) { throw new ClassNotFoundException(name); }
Class<?> clazz = defineClass(name, classBytes, 0, classBytes.length);
if (clazz == null ) throw new ClassNotFoundException(name);
return clazz;
}
private byte[] loadAndDecryptClassBytes(String name) throws IOException {
...
}
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
10
Eindeutigkeit von Klassen durch Klassenlader
Eindeutigkeit einer Klasse ist gegeben durch:
vollständigen Name, d.h. inklusive Paketnamen (z.B. java.sql.Date)
und Klassenlader, durch den sie geladen wurde
Dadurch ist es möglich, dass in einer VM
Klassen (mit gleichem Namen) von mehreren Quellen geladen und gleichzeitig
ausgeführt wird
Klassen in mehreren Versionen gleichzeitig geladen sind
Beispiel:
Applets geladen von mehreren Sites werden durch eigene Klassenlader
unterschieden
Pratikum SWE 2
MyAppletClass
MyAppletClass
cl1:ClassLoader
cl2:ClassLoader
© Institut für Systemsoftware Johannes Kepler Universität Linz
11
Security
Einführung
Klassenlader
Sicherheitsmanager und Berechtigungen
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
13
Sicherheitsmanager
Sicherheitsmanager erlaubt Prüfung, ob bestimmte (potentiell
gefährliche) Operationen erlaubt sind
unter anderem:
Zugriff (read, write) auf File
Öffnen einer Socket-Verbindung
Zugriff auf Systemeigenschaften
Beenden der Applikation
Erzeugen eines neuen Klassenladers
Zugriff auf die AWT-Eventqueue
Öffnen eines neuen Top-level Fensters
Installation eines neuen Sicherheitsmanagers
...
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
14
Installation eines Sicherheitsmanagers
Standardmäßig kein Sicherheitsmanager installiert
es werden daher auch keine Prüfungen durchgeführt
Installation eines SecurityManagers für eine Applikation mit
System.setSecurityManager(SecurityManager sm) oder beim Start des Programms
java -Djava.security.manager ...
Verfügbare Sicherheitsmanager:
SecurityManager: für Standardapplikationen
RMISecurityManager: für RMI-Applikationen, mit Laden von Code von Remote-Sites
AppletSecurity : bei Applets
Eigene Sicherheitsmanager als Ableitungen von SecurityManager
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
15
Sicherheitsmodell bei Java 2
Sicherheitsrichtlinien (SecurityPolices) bilden
Codequellen (code source)
auf Berechitgungsmengen (permissions)
ab, d.h. einer bestimmten Codequelle sind
eine Menge von Berechtigungen zugeordnet
Security Policy
CodeSource Codequellen und Berechtigungen sind
objektorientiert dargestellt
PermissionCollection
CodeBase
Permission
Certificate
Permission
Klassen CodeSource mit CodeBase und
Certificate
Klassensystem von Berechtigungsklassen
(Permission)
CodeSource
Mengen von Berechtigungen
(PersmissionCollection)
CodeBase
Certificate
PermissionCollection
Permission
Permission
Permission
Sicherheitsrichtlinien können in Policy-Files
spezifiziert werden (siehe später)
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
16
Ablauf beim Erzeugen eines ProtectionDomains
1.
Laden der Klasse durch
SecureClassLoader
(Basisklasse aller ClassLoader)
2.
Holen der Permissions aus
Policy aufgrund der Codebase
3.
Definieren der Klasse
(defineClass)
4.
Erzeugen einer ProtectionDomain
für die Klasse mit CodeSource
und Permissions
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
18
Operationen mit Sicherheitsprüfung
Ablauf Sicherheitsprüfung
Zugriff auf installierten SecurityManager über System.getSecurityManager
Wenn einer installiert ist (!= null), Aufruf der entsprechenden check-Methode beim
SecurityManager
Die check-Methode wirft bei Nicht-Bestehen der Prüfung eine SecurityException
Ausführung der eigentlichen Operation nach bestandener Prüfung
public void <checkedOperation>(...) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(...);
}
Kann SecurityException werfen!!
<uncheckedOperation>(...);
}
public void exit(int status) {
Beispiel: exit-Operation
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(new RuntimePermission("exitVM."+status));
}
Shutdown.exit(status);
Vereinfachte Version!
}
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
19
checkPermission
Prüfen von Permissions mit checkPermission von SecurityManager
public void checkPermission(Permission perm)
Ablauf: Prüfung einer Permission p
Pseudocode
checkPermission(Permission p) throws SecurityException {
for all classes clazz of methods on call stack {
permissionColl = clazz.getProtectionDomain().getPermissions();
if (! exists q in permissionColl with q.implies(p) )
throw SecurityException(...);
}
// permission p granted
}
Für alle Klassen der Methoden am Call-Stack
Zugriff auf PermissionCollection der Klasse
Wenn in PermissionCollection der Klasse keine Permission q existiert,
sodass die Permission q die geforderte Permission p impliziert
dann wirf eine SecurityException
Wenn alle Klassen von Methoden am Call-Stack Permission p haben
dann Operation ok (keine Execption)
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
20
Beispiel: read von SocketInputStream
Abgesicherte Methode!
Stack-Trace:
Pratikum SWE 2
Die Klassen aller Methoden am Stack müssen
die entsprechende Permission haben!
© Institut für Systemsoftware Johannes Kepler Universität Linz
21
Methode implies von Permission
Jede Permission implementiert eine Methode
boolean implies(Permission permission)
welche überprüft, ob sie die übergebene Permission „impliziert“
Beispiele:
RuntimePermission("*")
impliziert
RuntimePermission("ExitVM")
FilePermission(“C:\temp\*“, “read“)
impliziert
FilePermission(“C:\temp\MyFile“, “read“)
SocketPermission( “*:1024-65535", “connect”)
impliziert
SocketPermission “yourserver.com:1099", “connect“)
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
22
Hierarchie von Berechtigungsklassen
Werden mit unterschiedliche Parametern konfiguriert!
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
23
Policy-Files
Permissions werden durch Policy-Files vergeben
bestehen aus einer Folge von grant-Einträgen
Zuordnung von Codesource
zu einer Reihe von Permissions
die Codesource besteht aus
einer URL für die Codebase und
grant Codesource {
Permission_1;
Permission_2;
};
grant
codebase codebase-URL
signedby certificate-name ... {
Namen von vertrauenswürdigen Zertifikatsstellen
und jede Permission ist in der Form
Schlüsselwort permission
...
{
permission
Klassenname der Permission-Klasse
permission-className
target
action1, ...;
einem berechtigunsspezifischem Zielwert (z.B. ein ...
};
Verzeichnis oder eine Operation)
optional einer Liste von berechtigunsspezifischen
Aktionen
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
24
Beispiel eines Policy-File
Alle Codesources!
grant {
permission
permission
permission
permission
...
};
java.lang.RuntimePermission "stopThread";
java.net.SocketPermission "localhost:1024-", "listen";
java.util.PropertyPermission "java.version", "read";
java.util.PropertyPermission "java.vendor", "read";
grant codeBase "file:${java.home}/lib/ext/*" {
permission java.security.AllPermission;
};
Inkl. alle Unterverzeichnisse!
grant codeBase “www.ssw.uni-linz.ac.at/classes/" {
permission java.net.SocketPermission “*:1024-65535", “connect";
permission java.io.FilePermission “${user.home}${/}-“,
“read “, “ write “, “execute“;
...
};
...
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
25
Tabelle mit Permission-Einträgen (Auszug)
Permission
java.io.FilePermission
Target
Dateiziel
iava.net.SocketPermission
Socket-Ziel
java.util.PropertyPermission
Eigenschaftsziel
java.lang.RuntimePermission
createClassLoader
createSecurityManager
exitVM
stopThread
queuePrintJob
...
setDefaultAuthenticator
specifyStreamHandler
requestPassword-Authentication
showWindowWithoutWarningBanner
accessClipboard
acccessEventQueue
listenToAllAWTEvents
readDisplayPixels
getPolicy, setPolicy
...
java.net.NetPermission
java.awt.AWTPermission
java.security.SecurityPermission
...
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
Action
read, write, execute,
delete
accept,connect, listen,
resolve
read, write
26
Beispiel: SecurityManager
Installation eines SecurityManagers
durch
System.setSecurityManager(new SecurityManager());
oder beim Programmstart
java -Djava.security.manager at.jku.ssw.security.Main
Damit lassen sich Files nicht mehr lesen oder schreiben
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(filename)))) {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(line);
}
} catch (Throwable t) { System.out.println("Unable to read file: " + t); }
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(filename, true)))) {
writer.append("Hello World!\n");
} catch (Throwable t) { System.out.println("Unable to write file: " + t); }
Unable to read file: java.security.AccessControlException: access denied ("java.io.FilePermission" "test.txt" "read")
Unable to write file: java.security.AccessControlException: access denied ("java.io.FilePermission" "test.txt" "write")
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
27
Beispiel: SecurityManager
Policy-File mit Permissions ermöglicht Zugriff
grant codeBase "file:C:/.../UE03_WS/Security_Permissions_1/bin/‐" {
permission java.io.FilePermission "test.txt", "read";
permission java.io.FilePermission "test.txt", "write";
};
java -Djava.security.manager -Djava.security.policy=test.policy ...
Setzt Policy-File!
Setzt SecurityManager!
Pratikum SWE 2
© Institut für Systemsoftware Johannes Kepler Universität Linz
28