Security - ssw.jku.at

Werbung
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
Herunterladen