einführung klassenlader bytecode-prüfung...
TRANSCRIPT
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 1
Security
Einführung Klassenlader Bytecode-Prüfung
Sicherheitsmanager Berechtigungen
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 2
Sicherheitsmechanismen in Java
• Sicherheit ist integraler Bestandteil von Java – Sicherheit: Code darf keinen Schaden anrichten
• Sprachliche Entwurfsmerkmale – Bereichsprüfung bei Arrays – sichere Typcasts – keine Zeigerarithmetik
• Zugriffskontrolle – Dateizugriff – Netz-Zugriff
• Codesignierung
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 3
Komponenten des Sicherheitsmanagement
• Virtuelle Maschine prüft – Arrayzugriffe – Typcasts – Integrität des Bytecodes
• Klassenlader – Laden von Code
• Sicherheitsmanager – erlaubte und verbotene Operationen und Zugriffe
• Verschlüsselung (java.security) – Codesignierung
• Java Authentication and AuthorizationService (JAAS)
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 4
Laden von Klassen
• Klassen werden erst bei Bedarf geladen
• Ladeprozess – Laden der Hauptklasse – Laden der Superklasse der Hauptklasse – Ausführen der Methode main – Laden benötigter Klassen beim Ausführen von main
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 5
Klassenlader
• ClassLoader laden Code-Images (zB: von Dateien) • Jede Klasse ist eindeutig benannt innerhalb eines ClassLoaders
• Jede Klasse kennt ihren ClassLoader
• ClassLoader können Klassen – über Namen laden
– aus Byte-Arrays definieren
Class class = x.getClass(); ClassLoader loader = class.getClassLoader();
Class myClass = loader.loadClass("MyClass");
byte[] classCode = ...; Class defClass = loader.defineClass("DefClass", classCode, 0, classCode.length);
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 6
Arten von Klassenladern
• Bootstrap-Klassenlader – Klassen aus rt.jar
• Benutzerdefinierte Klassenlader – Erweiterungsklassenlader
• Klassen aus jre/lib/ext – Systemklassenlader (Applikationsklassenlader)
• Anwendungsklassen aus Klassenpfad (CLASSPATH)
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 7
Hierarchie der Klassenlader
• Klassenlader – hat einen Parent – delegiert Laden an Parent weiter – kann der Parent die Klasse nicht laden versucht es der
Klassenlader selbst
bootstrap class loader
extension class loader
system class loader
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 8
Explizites Laden von Klassen
• Klassen können explizit geladen werden – Ohne benannten Klassenlader
Es wird der Klassenlader der Klasse verwendet, in dem der Code steht
– Mit Klassenlader
• Zugriff auf Klassenlader – es gibt einen Standard-Systemklassenlader
– jeder Thread hat einen ContextClassLoader
Class.forName(className);
ClassLoader loader = ... loader.loadClass(className);
ClassLoader.getSystemClassLoader();
Thread t = Thread.currentThread(); t.getContextClassLoader();
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 9
Eindeutigkeit von Klassen durch Klassenlader
• Eindeutigkeit einer Klasse ist gegeben durch – vollständigen Name, zB: java.util.ArrayList – und Klassenlader, durch den sie geladen wurde
• Dadurch ist es möglich, in einer VM – Code von mehreren Quellen zu laden und auszuführen – Klassen in mehreren Versionen geladen werden
• Beispiel – Applets geladen von mehreren Seiten werden durch
Klassenlader unterschieden
MyApplet
cl1 : ClassLoader cl2 : ClassLoader
MyApplet
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 10
Bytecode-Prüfung
• ClassLoader lädt Code in den Speicher • Die VM prüft den Bytecode • Prüfungen für Bytecode sind wichtig
– mit javac übersetzter Bytecode ist grundsätzlich sicher aber • Code kann von Hand verändert sein • Fehler im Compiler
• Folgende Prüfungen werden durchgeführt – korrektes Dateiformat – keine Ableitung einer final Klasse – jede Klasse (außer Objekt) braucht eine Superklasse – Felder und Methoden auf Typ und Namen – Operanden-Stack durch alle Pfade gleich – alle Variablen initialisiert – Argumente bei Methoden aufrufen korrekt – Feldzuweisungen mit den richtigen Typen – Passen die Operatoren zu den Operanden – keine Zugriffsverletzungen gemacht – Zugriffe auf lokale Variablen innerhalb des Gültigkeitsbereichs – kein Überlauf des Laufzeit-Stacks
Kann ausgeschaltet werden:
java -noverify Foo
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 11
Sicherheitsmanager
• Prüft ob potentiell gefährliche Operationen erlaubt sind, Beispiele: – aktueller Thread neuen Klassenlader erzeugen darf – aktueller Thread eine Unterprozess erzeugen darf
– aktueller Thread eine DLL laden darf – aktueller Thread auf Systemeigenschaften zugreifen und diese modifizieren darf
– aktueller Thread eine Datei oder Verzeichnis lesen, schreiben oder löschen darf
– aktueller ThreadSocket-Verbindung zu einem Host und Port öffnen – aktueller Thread auf eine Verbindung zu einem Host und Port aufbauen darf
– aktueller Thread bestimmte Methoden eines anderen Threads oder ThreadGroup aufrufen darf
– eine Klasse einen Druckauftrag starten darf
– eine Klasse auf die Zwischenablage des Systems zugreifen darf
– eine Klasse auf die AWT-Ereignisqueue zugreifen darf – aktueller Thread ein Fenster auf oberster Ebene öffnen darf
– aktueller Thread einen eigenen Sicherheitsmanager installieren darf – ein Thread eine Applikation beenden darf
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 12
Ablauf einer Prüfung
• Zugriff auf installierten SecurityManager über System.getSecurityManager
• Wenn installiert (d.h. nicht 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.checkOperation(...); // may throw SecurityException } uncheckedOperation(...); }
public void exit(int status) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkExit(status); } Shutdown.exit(status); }
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 13
Installation eines Sicherheitsmanagers
• Bei Applikationen ist standardmäßig kein Sicherheitsmanager installiert; es werden daher keine Prüfungen durchgeführt
• Installation eines Sicherheitsmanagers – System.setSecurityManager(SecurityManager sm) – java -Djava.security.manager …
• In Java 2 stehen zwei Sicherheitsmanager zur Verfügung SecurityManager: für Standardapplikationen RMISecurityManager: für RMI-Applikationen
• Eigene Sicherheitsmanager können als Ableitungen realisiert werden
• Bei Applets: – bei Browsern wird automatisch der SecurityManager AppletSecurity
installiert – damit laufen Applets in der Sandbox
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 14
Sicherheitsrichtlinien (SecurityPolicy)
• Sicherheitsrichtlinien bilden
– Codequellen (code source) – auf Berechitgungsmengen
(permissions)
ab, d.h. einer bestimmten Codequelle sind eine Menge von Berechtigungen zugeordnet
• Codequellen und Berechtigungen sind objektorientiert implementiert
– Klassen CodeSource, CodeBase und Certificate
– Hierarchie von Berechtigungsklassen (Permissions)
• Sicherheitsrichtlinien können in Dateien (Policy-Files) spezifiziert werden
SecurityPolicy
CodeSource
CodeBase
Certificate
PermissionCollection
Permission
Permission
CodeSource
CodeBase
Certificate
PermissionCollection
Permission
Permission
Permission
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 15
Berechtigungsklassen
Permission
AllPermission BasicPermission FilePermission SocketPermission
AudioPermission NetPermission ReflectedPerm
ission SecurityPermission
AWTPermission PropertyPermi
ssion RuntimePermi
ssion SerializablePer
mission
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 16
Standardmechanismus für Berechtigungsprüfungen
• Basiert auf Permissions • Konzepte
– Permission-Objekte, PermissionCollections und Prüfen von Permission-Objekten gegen PermissionCollections
– SecureClassLoader (Basisklasse aller ClassLoader) mit der Installation von ProtectionDomains beim Laden von Klassen
– Policy-Objekte, die Richtlinien in der Form von CodeSource und PermissionCollections liefern
• Berechtigungen werden bei Klassen in ProtectionDomains verwaltet
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 17
Erzeugen einer ProtectionDomain
1 Laden der Klasse durch SecureClassLoader
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
SecureClass Loader
Class Protection Domain
Permission Collection
Certificate Permission
Policy
CodeSource
URL
* *
4:create
3:defineClass
1:loadClass(className)
2:getPermission(codebase)
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 18
Ablauf einer Prüfung
• Sammlung aller ProtectionDomains der Klassen aller Methoden auf dem Laufzeitstack
• Zugriff auf die PermissionCollection jeder ProtectionDomain • Prüfen, der Permission aus aktuellen Operation gegen die
PermissionCollection
• Wenn alle ProtectionDomains die Operation erlauben, – Prüfung bestanden – sonst Auslösung einer SecurityException
checkForPermission(Permission p) { for all classes of methods on callstack { protectionDomain = class.getProtectionDomain(); permissions = protectionDomain.getPermissions(); if (operation checked against permissions != ok) throw SecurityException(...); } return; }
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 19
FileOutputStream fos = null; try { fos = new FileOutputStream(fileName); write(fos, model); } catch (Exceptionexc) { Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, exc.getMessage(), exc); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log( Level.SEVERE, e.getMessage(), e); } } }
Beispiel: Schreiben in eine Datei
Die Klassen aller Methoden am Stack müssen die entsprechende Permission haben!
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 20
Prüfen von Permissions gegen PermissionCollections
Permission-Objekte werden verwendet für
• Definition von Berechtigungen der Klassen (PermissionsCollections der ProtectionsDomains)
• Definition der notwendigen Berechtigung, um eine Operation auszuführen
zB: wird bei checkExit folgendes ausgeführt
Eine Permission p1 besteht Test gegenüber einer PermissionCollection c,
wenn eine Permission p2 aus c die Permission p1 impliziert!
public void checkExit(int status) { checkPermission(new RuntimePermission("exitVM")); }
Notewendige Permission, um System.exit(int) auszuführen.
public void exit(int status) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkExit(status); } Shutdown.exit(status); }
Beis
pie
l exit
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 21
Methode implies der Klasse Permission
• Jede Permission implementiert boolean implies(Permission permission) liefert true wenn die Permission, die übergebene Permission enthält, ansonsten false
• Beispiele RuntimePermission("*") impliziert RuntimePermission("ExitVM")
FilePermission("C:\temp\*", "read,write") impliziert FilePermission("C:\temp\x.txt", "read")
SocketPermission("*:1024-65535", "connect") impliziert SocketPermission("ssw.jku.at:1099", "connect")
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 22
Policy-Klasse und Policy-Dateien
• SecureClassLoader erhält die eingestellten Sicherheitsrichtlinien vom installierten Policy-Objekt
• Standardmäßig ist das ein Objekt der Klasse PolicyFile, das die Richtlinien aus Richtliniendateien liest
• Standard sind zwei Policy-Dateien – in der Java-Installation: jre/lib/security/java.policy – im Basisverzeichnis des Benutzers: .java.policy
• Policy-Dateien können beim Programmstart angegeben – java –Djava.security.policy=MyPol.policy MyApp
oder im Programm über Systemproperties eingestellt werden – System.setProperty("java.security.policy", "MyPol.policy");
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 23
Einstellungen zum Security-Mechanismus
• Globale Einstellungen in – jre/lib/security/java.policy
• Beispiele – Policy-Klasse
policy.provider=sun.security.provider.PolicyFile
– URLs von Policy-Dateien policy.url.1=file:${java.home}/lib/security/java.policy policy.url.2=file:${user.home}/.java.policy
– Soll die Angabe weiterer Policy-Dateien erlaubt sein policy.allowSystemProperty=true
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 24
Format der Policy-Dateien
• Folge von grant-Einträgen mit – Codesource – Permissions
• Codesource mit – URL der Codebase – vertrauenswürdige Zertifikatstellen
• Permission mit – Klassenname der Permission – Zielwert – Aktionen
grant Codesource { Permission_1; Permission_2; }
grant codebase codebase-URL certificate-name ... {
...
... { permission className target action, ... ... };
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 25
Beispiel einer Policy-Datei grant codeBase "file:${java.home}/lib/ext/*" {
permission java.security.AllPermission; };
grant { permission java.lang.RuntimePermission "stopThread"; permission java.net.SocketPermission "localhost:1024-", "listen"; permission java.util.PropertyPermission "java.version", "read"; permission java.util.PropertyPermission "java.vendor", "read"; ...
};
grant { permission javax.crypto.CryptoPermission "DES", 64; permission javax.crypto.CryptoPermission "DESede", *; ...
};
grant codeBase "http://www.ssw.uni-linz.ac.at/classes/" { permission java.net.SocketPermission "*:1024-65535", "connect"; permission java.io.FilePermission "${user.home}${/}-", "read,write,execute“; ...
}; ...
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 26
Beispiele von Permissions Permission Target Ac0on
java.io.FilePermission Dateipfad read,write,execute,delete
java.net.SocketPermission Host:Portrange accept,connect,listen,resolve
java.u?l.PropertyPermission NamedesSystemproper?es read,write
java.lang.Run?mePermission createClassLoadersetSecurityManagerexitVMstopThread...
java.net.NetPermission setDefaultAuthen?catorsetCookieHandlersetResponseCache...
java.awt.AWTPermission accessClipboardwatchMousePointerreadDisplayPixels…
java.security.SecurityPermission getPolicysetPolicy…
Praktikum aus Softwareentwicklung 2 © Markus Löberbauer 27
Literatur
• Java SE 6 Documentation – http://java.sun.com/javase/6/docs/technotes/guides/security/index.html
• Krüger, Stark, Handbuch der Java-Programmierung, 5. Auflage, Addison Wesley, 2007, Kapitel 48 – http://www.javabuch.de
• Ullenboom, Java ist auch eine Insel, 7. Auflage, Galileo Computing, 2007, Kapitel 25 – http://www.galileocomputing.de/openbook/javainsel7/