|
|||
|
|
Client-Server-Security |
||
|
Dieser Artikel ist im JavaSpektrum 2/99 erschienen. Vielen Dank an SIGS für die Genehmigung zur Veröffentlichung auf dieser Webseite! Sicherheitsaspekte für Client-/Server-SzenarienMeist hört man auf die Frage nach Sicherheit unter Java immer wieder dieselben Antworten: Sandbox und signierte Applets. Aber es gibt fast keine solchen Applets und
das Thema Security umfasst viel mehr als nur diese zwei Facetten. Bei Client-/Server-Architekturen gibt es drei Dinge, die vor Manipulationen und Fehlern zu schützen sind: Code und Ressourcen auf Client und Server sowie die Kommunikation zwischen den beiden (s. Abb.1).
Die Programmiersprache Java wurde unter besonderer Beachtung von Sicherheitsaspekten entwickelt. Die
Sprache selbst und die im JDK enthaltenen Bibliotheken reduzieren dabei einen Großteil der Risiken oder stellen zumindest Mechanismen zu deren Vermeidung bereit, die man in anderen Sprachen selbst
implementieren oder zukaufen müsste. Aspekte der Client-/Server-SecurityFür die drei in Abb. 1 gezeigten Angriffspunkte gibt es jeweils verschiedene Angriffsmöglichkeiten und entsprechende Schutzmechanismen:
Schutz des Servers vor
Schutz der Kommunikationsverbindung vor
Zunächst zum Schutz des ClientsEin spezielles Problem von im Inter-/Intranet verteilten Applikationen ist, dass der Nutzer oft gar nicht damit rechnet, dass dort Gefahren durch bösartige oder fehlerhafte Anwendungen lauern könnten, da er
ja nur eine Webseite anwählt. Im Gegensatz zu lokalinstallierten Programmen, die vor einer Freigabe zunächst in einer Testumgebung evaluiert werden können, starten Java-Applets sofort und automatisch.
Auch eine Firewall hilft hier nichts, denn der heruntergeladene Code wird lokal ausgeführt. Man könnte nur alle Applets sperren und damit auch sämtlichen Nutzen verlieren. JDK 1.0 - SandboxBei den JDK-Versionen 1.0.x wurde die Sandbox eingeführt. Man ging hier von der Prämisse aus, dass jeglicher Java-Code, der auf dem lokalen Rechner installiert ist (CLASSPATH), als sicher zu betrachten ist und alles, was von außen kommt, als unsicher. Vor diesem potentiell gefährlichen Code müssen alle lokalen Daten und Ressourcen vor Manipulation und Informationsweitergabe geschützt werden. Dazu zählt insbesondere:
Besonderen Schutz genießen zudem die Systemklassen (z. B. java.*), die nichtüberladen bzw. ersetzt werden dürfen, um ein Ausschalten der Sicherheitsmechanismenbeispielsweise durch den Austausch der Klasse SecurityManager durch eineDummy-Implementierung zu verhindern. JDK 1.1 - signierte AppletsDie Restriktionen der Sandbox waren sehr stark. Es war zum Beispiel nicht möglich, einen Textverabeitungs-Client als Java-Applet im Intranet zu schreiben, der Dateien lokal drucken oder
speichern kann. Deshalb hat Sun bei der Version 1.1 des JDK die Möglichkeit geschaffen, besonders vertrauenswürdigen Applets zusätzliche Rechte einzuräumen.
Insbesondere der letzte Punkt war kritisch, denn zum Beispiel ist es nicht möglich, ein browser-unabhängiges signiertes JAR im Inter-/Intranet bereitzustellen, weil Microsoft für den Internet Explorer sein proprietäres cab-Format verlangt und Netscape-eigene Security-Klassen benutzt. Die Administration der Rechte auf den Clients ist bei jedem Browser anders (z. B. HotJava, Internet Explorer, Navigator und appletviewer pflegenje eigene Policy-Datenbanken, z. B. als Policy-Datei oder in Form einer Reihe von Einträgen in der Registry).). Java 2 - Protection DomainsBei der neuen Java 2 Plattform (ehemals JDK 1.2) hat man diese Probleme aufgegriffen (s. auch [Kue98]
). So ist es jetzt beispielsweise möglich, die Zugriffsrechte via Policies für jeglichen Java-Code zu definieren, nicht nur für Applets aus dem Internet. Dabei kann zum Beispiel ein Administrator die Rechte
unternehmensweit vorgeben, der Endanwender hat nur noch die Möglichkeit, diese weiter zu verfeinern (d. h. weiter einzuschränken, wenn der Administrator ihm dieses Recht zugesteht). SchutzmechanismenDer Schutz erfolgt in mehreren Schritten (Abb. 2). Schon zur Entwicklungszeit unterstützt Java durch das Sprachdesign die Entwicklung sicheren Codes. Dazu zählen zum Beispiel der Verzicht auf direkte
Speichermanipulation, die strenge Typisierung und die automatische Garbage Collection. Somit werden durch Programmierfehler versehentlich “unsicher” gemachte Anwendungen, die Speicherfehler
verursachen oder Memory Leaks haben, von vornherein ausgeschlossen. Bei der Veröffentlichung, dem Publishing, des Codes, zum Beispiel der Bereitstellung auf einem Webserver,
hat man die Möglichkeit, signierte Archive zu erstellen, die die Integrität des Codes gewährleisten. Im JDK 1.1 geschieht dies mit dem Werkzeug javakey, unter Java 2 mit jarsigner. Lokaler StartFalls die Anwendung lokal gestartet wurde, gibt es keinerlei Sicherheitsbeschränkungen (JDK 1.0 und 1.1). Start vom NetzFalls die Anwendung vom Netz gestartet wurde, wird zwangsläufig eine gesicherte Variante des ClassLoaders (AppletClassLoader) benutzt, der folgende Voraussetzungen für die Ausführung garantiert:
Für die Erweiterungen in Java 2 wird ein SecureClassLoader benutzt, der auch bei lokalen Anwendungen benutzt werden kann.
Das letzte Kettenglied stellt der SecurityManager dar. Dieser existiert zum Beispiel zwangsläufig, wenn
ein Applet aus dem Inter-/Intranet geladen wurde oder optional bei Applikationen. Wenn es nun einen solchen gibt, werden durch ihn zur Laufzeit alle Ressourcenzugriffe auf die Einhaltung der Policies geprüft
. Falls diese verletzt werden, generiert der SecurityManager eine SecurityException. ZusammenfassungDer Client wird geschützt vor:
Diese Einschränkungen können mit JDK 1.1 und Java 2 optional für Klassen aus trustedCode-Quellen aufgehoben werden.
In diesem Zusammenhang ist auch an das Sicherheitsbewußtsein der Anwender zu appellieren. Wenn ein Heimanwender in seiner Browser-Konfiguration alles erlaubt oder ein Unternehmen die Zugriffsrechte in der Browser-Konfiguration nicht oder zu unsicher vorgibt, muss man sich nicht wundern, wenn irgendein Applet etwas "zerschießt". Nun zum Schutz des ServersZunächst gibt es die grundsätzliche Notwendigkeit, einen Server zu sichern, z. B. vor Ausfall oder gegen
Manipulation. Diese Risiken sind jedoch nicht sprachspezifisch und daher nicht Inhalt dieses Artikels. Schutz gegen unberechtigte ZugriffeMan schützt Server-Zugriffe üblicherweise durch Authentifizierung und Identifizierung, damit kein Unberechtigter auf den Server zugreifen kann, der unberechtigt oder in falschem Namen einen Dienst in
Anspruch nehmen oder gar den Server und dessen Daten beschädigen könnte. Schutz vor manipulierten Clients und falschen VersionenDamit der Server ausschließlich von zugelassenen Clients benutzt werden kann, sollte er den Client-Code
überprüfen können. Damit will man vermeiden, dass veraltete Client-Versionen benutzt werden und dass ein manipuliertes Client-Programm geschrieben werden kann, das sich beim Verbindungsaufbau normal
verhält, aber bei sicherheitskritischen Zugriffen verändert ist.
Wie oben ausgeführt, gibt es für die Server-Seite keine sinnvolle Möglichkeit, anhand von Versionskennzeichen und der Tatsache, dass der Code von einem Webserver heruntergeladen wurde,
festzustellen, dass der Client-Code unmodifiziert abläuft. Die verwendeten Kommunikationsprotokolle einer Client-/Server-Applikation können zwar die übertragenen Daten sichern, stellen aber auch keinen
Mechanismus zur Verifikation der Unversehrtheit des Client-Codes dar.
Vereinbarung von Session KeysZwischen Client und Server werden Session Keys vereinbart (z. B. lange Zufallszahlen) und übertragen. Basierend auf diesem Wert wird über die in der Package java.security enthaltenen Algorithmen ein Hash
-Wert berechnet, der über die gesamte Klasse gebildet wird und damit die Integrität der Client-Klassen sicherstellt.
Dynamisches Laden von generischen KlassenDie abstrakte Klasse ClassLoader definiert Methoden zum dynamischen Laden und Generieren von Klassen
(zur Laufzeit). Somit kann der AppletClassLoader oder ein eigener ClassLoader die sicherheitskritischen Klassen erst zur Laufzeit vom Server bekommen. Wenn ein Server-Prozess diese Klassen dynamisch
generiert und Informationen zum Aufbau der Klassen übers Netz lädt, können sie zum Client übertragen und dort dynamisch mit defineClass und resolveClass erzeugt werden. Lokale Manipulationsmöglichkeiten von heruntergeladenem CodeIm Falle von Applets wird Java-Bytecode von Webbrowsern geladen und bis zu deren Beendigung im Speicher gehalten. Die Implementierung ist herstellerabhängig, zum Beispiel könnten die Klassen lokal in
temp-Verzeichnissen auf der Festplatte abgelegt werden und wären damit zugänglich. Selbst wenn die Klassen nur im Speicher liegen würden, könnte sie ein geschickter Hacker durch einen Speicherabzug
oder über die Auslagerungsdatei rekonstruieren. Verlagerung der kritischen Funktionalität auf den ServerEine andere Variante zur Verminderung der Angriffsfläche auf dem Client besteht darin, dort nur minimale
Funktionalität ablaufen zu lassen und alle kritischen Code-Teile auf dem Server zu halten. Dies ist der sprichwörtliche Thin Client, der nur Oberfläche darstellt und einfache Validierungen durchführt. In Java
bieten sich dafür Mechanismen wie Servlets, RMI oder CORBA an. ZusammenfassungReine Client- oder Server-Lösungen (Applets bzw. Servlets) sind für den Server relativ sicher, kritisch ist die Etablierung einer Applikationsschnittstelle. Der Server sollte dann durch Authentifizierung und Identifizierung geschützt werden. Der Server sollte zudem durch Session Keys und Zentralisierung des kritischen Codes vor unzulässigem Client-Code gesichert werden. Der verbleibende Client-Code sollte durch Code-Verwürfler vor Decompilierung geschützt werden. Schutz der KommunikationsverbindungFalls eine Client-Server-Kommunikation ausgeführt wird, erfolgt diese über normale Kommunikationsprotokolle wie TCP/IP Port/Socket-Kommunikation, Datagramme, http oder IIOP. Diese
Protokolle haben an sich recht wenig mit Java zu tun und bieten in der Regel ihre eigenen Sicherheitsmechanismen an. In [Vogl98] finden Sie ein Beispiel. Verschlüsselung durch Security-KlassenDie Verschlüsselung und Schlüsselgenerierung erfolgt in Java mittels ,PublicKey"-Verfahren nach der Java
Cryptographic Architecture (JCA). Dies geschieht mit Klassen und Schnittstellen des Pakets java.security. Hier sind jedoch nur die Schnittstellen für die Benutzung der Verfahren festgelegt, nicht jedoch das
Verfahren (die Implementierung) selbst. Es ist lediglich definiert, dass Einweg-Hash-Funktionen Verwendung finden. Diese produzieren einen Ausgabe-String fester Länge (Hash oderDigest). Man nennt
diese Algorithmen deshalb auch MessageDigest-Algorithmen. Arten des SchutzesDie Kommunikationsverbindung muss vor verschiedenen Angriffsmöglichkeiten gesichert werden. Vor dem Mithören und vor dem unberechtigten Zugriff schützt die Verschlüsselung der Daten. Vor dem Abfangen
und der verfälschten Weitergabe schützen digitale Signaturen ebenso wie vor der Ableugung eines Vorganges beziehungsweise einer Identität. FazitDieser Artikel hat gezeigt, was bei der Entwicklung sicherer Anwendungen zu bedenken ist. Die Ursache vieler Risiken liegt in der Offenheit von Internet-Anwendungen,Client-/Server- und Multi-Tier -Architekturen, nicht an der Sprache Java. Ganz im Gegenteil. Java liefert für eine Vielzahl von Problemen fertige Lösungen mit (im Gegensatz zu anderen Technologien wie ActiveX im Internet). Es ist an den Entwicklern, diese richtig einzusetzen. Literatur[Kue98] R. Kuehnel, Tutorial über die Programmierung von Java-Applets, 12. Teil, JavaSpektrum, November/Dezember 1998 [Vogl98] W. Vogl, Java und ,Secure Socket Layer", JavaSpektrum, September/Oktober1998 |
|||
Begriffe |
|||
|
CA |
Certification Authority, Zertifizierungsbehörde, die die Echtheit von Zertifikaten bestätigt |
||
|
digitale Signatur |
ein für die Daten charakteristischer "Fußabdruck" wird bei "Public-Key"-Verfahren zur Unterzeichnung verwendet und kann mit dem öffentlichen Schlüssel überprüft werden. |
||
|
JAR |
Java ARchive, komprimierter Satz von Klassen und ressourcen, möglicherweise mit Zertifikat |
||
|
JCA |
Java Cryptographic Architecture, abstrakter Satz von Krypto-Klassen und -Schnittstellen für verfahrensunabhängige Anwendung von Kryptologie in Java |
||
|
JCE |
Java Cryptography Extension, exportbeschränktes kryptographisches Zusatzpaket des JDKs |
||
|
Policy |
unternehmensweite oder lokale Definition von Rechten mittels Zugriffskontrollisten für Code aus bestimmter Quelle und/oder mit Zertifikaten |
||
|
Protection Domain |
abgesicherte Laufzeitumgebung für Code aus einer bestimmten Quelle (URL), der durch lokale Policies bestimmte Rechte zugewiesen sind |
||
|
Public Key Verfahren |
asymmetrische Verschlüsselungsmethode mit einem privaten (geheimen) und einem öffentlichen Schlüssel, z.B. RSA |
||
|
Security Manager |
durch den AppletClassLoader instantiiertes Objekt, das die Befolgung der Policies überwacht, im Java 2 ersetzt durch AccessController |
||
|
Zertifikat |
Bestätigung der Identität eines Unternehmens oder einer Person durch einen vertrauenswürdigen Dritten, gesichert durch eine digitale Signatur, z.B. X.509 V3 |
||
Manipulation von herunter geladenem Code |
|||
Java-DecompilerJavaDis von Wingsoft (www.wingsoft.com) |
|||
Code-VerwürflerOuyaSafe (www.wingsoft.com) |
|||
|
|
|||
© 2006 Hawlitzek IT-Consulting GmbH,
|
|||