Grundlegendes zu den Schlüsseln für die Java-Sicherheit - Sandbox und Authentifizierung

Möglicherweise haben Sie von der neuesten Sicherheitslücke in JDK 1.1 und HotJava 1.0 gehört, die kürzlich vom Secure Internet Programming-Team der Princeton University (unter der Leitung eines der Autoren) entdeckt wurde. Wenn Sie die ganze Geschichte wollen, lesen Sie weiter. Die Java-Sicherheit bietet jedoch mehr als die Besonderheiten dieser neuesten Sicherheitslücke. Lassen Sie uns eine Perspektive bekommen.

Java-Sicherheit und öffentliche Wahrnehmung

Jeder weiß, dass Sicherheit für Java eine große Sache ist. Immer wenn eine Sicherheitslücke entdeckt wird, wird die Geschichte sehr schnell in die Computernachrichten (und manchmal auch in die Wirtschaftsnachrichten) übertragen. Sie werden nicht überrascht sein zu erfahren, dass die beliebte Presse comp.risks und andere sicherheitsrelevante Newsgroups überwacht . Sie wählen Sicherheitsgeschichten aus, um sie scheinbar zufällig hervorzuheben. Da Java heutzutage so heiß ist, drucken sie fast immer Java-Sicherheitsgeschichten.

Das Problem ist, dass die meisten Nachrichten die Löcher überhaupt nicht gut erklären. Dies könnte zu einem klassischen "Cry Wolf" -Problem führen, bei dem sich die Leute daran gewöhnen, "die Sicherheitsgeschichte dieser Woche" zu sehen und sich nicht über die sehr realen Risiken ausführbarer Inhalte zu informieren. Darüber hinaus neigen Anbieter dazu, ihre Sicherheitsprobleme herunterzuspielen, wodurch die Hauptprobleme weiter verwirrt werden.

Die gute Nachricht ist, dass das JavaSoft-Sicherheitsteam es ernst meint, Java sicher zu machen. Die schlechte Nachricht ist, dass die Mehrheit der Java-Entwickler und -Nutzer den Hype glauben kann, der von Ereignissen wie JavaOne ausgeht, bei denen Sicherheitsprobleme nicht viel Luft bekommen. Wie wir in unserem Buch " Java-Sicherheit: Feindliche Applets, Löcher und Gegenmittel" gesagt haben , hat Sun Microsystems viel zu gewinnen, wenn Sie glauben, dass Java vollständig sicher ist. Es ist richtig, dass die Anbieter große Anstrengungen unternommen haben, um ihre Java-Implementierungen so sicher wie möglich zu gestalten, aber die Entwickler wollen keinen Aufwand. Sie wollen Ergebnisse.

Da mit einem Java-fähigen Webbrowser Java-Code in eine Webseite eingebettet, über das Internet heruntergeladen und auf einem lokalen Computer ausgeführt werden kann, ist die Sicherheit ein wichtiges Anliegen. Benutzer können Java-Applets mit außergewöhnlicher Leichtigkeit herunterladen - manchmal ohne es zu wissen. Dies setzt Java-Benutzer einem erheblichen Risiko aus.

Die Designer von Java sind sich der vielen Risiken bewusst, die mit ausführbaren Inhalten verbunden sind. Um diesen Risiken entgegenzuwirken, haben sie Java speziell unter Berücksichtigung von Sicherheitsbedenken entwickelt. Das Hauptziel war es, das Sicherheitsproblem direkt anzugehen, damit naive Benutzer (z. B. die Mehrheit der Millionen von Web-Surfern) keine Sicherheitsexperten werden müssen, nur um das Web sicher zu lesen. Dies ist ein bewundernswertes Ziel.

Die drei Teile der Java-Sandbox

Java ist eine sehr mächtige Entwicklungssprache. Nicht vertrauenswürdige Applets sollten nicht auf diese gesamte Leistung zugreifen dürfen. Die Java-Sandbox verhindert, dass Applets viele Aktivitäten ausführen. Das beste technische Dokument zu Applet-Einschränkungen ist "Low Level Security in Java" von Frank Yellin.

Die Java-Sicherheit basiert auf drei Verteidigungselementen: dem Byte Code Verifier, dem Class Loader und dem Security Manager. Zusammen führen diese drei Zinken Lade- und Laufzeitprüfungen durch, um den Dateisystem- und Netzwerkzugriff sowie den Zugriff auf Browser-Interna einzuschränken. Jeder dieser Zinken hängt in irgendeiner Weise von den anderen ab. Damit das Sicherheitsmodell ordnungsgemäß funktioniert, muss jedes Teil seine Aufgabe ordnungsgemäß erfüllen.

Der Bytecode-Verifizierer :

Der Byte Code Verifier ist der erste Stift des Java-Sicherheitsmodells. Wenn ein Java-Quellprogramm kompiliert wird, wird es in plattformunabhängigen Java-Bytecode kompiliert. Java-Bytecode wird "verifiziert", bevor er ausgeführt werden kann. Dieses Überprüfungsschema soll sicherstellen, dass der Bytecode, der möglicherweise von einem Java-Compiler erstellt wurde oder nicht, den Regeln entspricht. Schließlich könnte Bytecode durchaus von einem "feindlichen Compiler" erstellt worden sein, der Bytecode zusammengestellt hat, der die virtuelle Java-Maschine zum Absturz bringen soll. Das Überprüfen des Bytecodes eines Applets ist eine Möglichkeit, mit der Java nicht vertrauenswürdigen externen Code automatisch überprüft, bevor er ausgeführt werden darf.Der Verifier überprüft den Bytecode auf verschiedenen Ebenen. Der einfachste Test stellt sicher, dass das Format eines Bytecode-Fragments korrekt ist. Auf einer weniger grundlegenden Ebene wird auf jedes Codefragment ein eingebauter Theorembeweiser angewendet. Der Theorembeweiser hilft sicherzustellen, dass der Bytecode keine Zeiger fälscht, keine Zugriffsbeschränkungen verletzt oder auf Objekte mit falschen Typinformationen zugreift. Der Überprüfungsprozess hilft zusammen mit den Sicherheitsfunktionen, die über den Compiler in die Sprache integriert sind, dabei, eine Reihe von Sicherheitsgarantien zu erstellen.

Der Applet-Klassenladeprogramm :

Der zweite Pfeiler der Sicherheitsabwehr ist der Java Applet Class Loader. Alle Java-Objekte gehören zu Klassen. Der Applet Class Loader bestimmt, wann und wie ein Applet einer laufenden Java-Umgebung Klassen hinzufügen kann. Ein Teil seiner Aufgabe besteht darin, sicherzustellen, dass wichtige Teile der Java-Laufzeitumgebung nicht durch Code ersetzt werden, den ein Applet zu installieren versucht. Im Allgemeinen können in einer laufenden Java-Umgebung viele Klassenlader aktiv sein, von denen jeder seinen eigenen "Namensraum" definiert. Mithilfe von Namensräumen können Java-Klassen je nach Herkunft in verschiedene "Arten" unterteilt werden. Der Applet Class Loader, der normalerweise vom Browserhersteller bereitgestellt wird, lädt alle Applets und die Klassen, auf die sie verweisen. Wenn ein Applet über das Netzwerk geladen wird, empfängt der Applet Class Loader die Binärdaten und instanziiert sie als neue Klasse.

Der Sicherheitsmanager :

Der dritte Pfeiler des Java-Sicherheitsmodells ist der Java Security Manager. Dieser Teil des Sicherheitsmodells schränkt die Art und Weise ein, in der ein Applet sichtbare Schnittstellen verwenden kann. Somit implementiert der Sicherheitsmanager einen Großteil des gesamten Sicherheitsmodells. Der Security Manager ist ein einzelnes Modul, das Laufzeitprüfungen für "gefährliche" Methoden durchführen kann. Code in der Java-Bibliothek konsultiert den Sicherheitsmanager, wenn ein gefährlicher Vorgang versucht wird. Der Sicherheitsmanager hat die Möglichkeit, ein Veto gegen den Vorgang einzulegen, indem er eine Sicherheitsausnahme generiert (der Fluch der Java-Entwickler überall). Vom Sicherheitsmanager getroffene Entscheidungen berücksichtigen, welcher Class Loader die anfordernde Klasse geladen hat. Integrierte Klassen erhalten mehr Berechtigungen als Klassen, die über das Netz geladen wurden.

Nicht vertrauenswürdig und in den Sandkasten verbannt

Zusammen bilden die drei Teile des Java-Sicherheitsmodells die Sandbox. Die Idee ist, die Möglichkeiten eines Applets einzuschränken und sicherzustellen, dass es den Regeln entspricht. Die Sandbox-Idee ist ansprechend, da Sie damit nicht vertrauenswürdigen Code auf Ihrem Computer ausführen können, ohne sich darüber Gedanken machen zu müssen. Auf diese Weise können Sie ungestraft im Internet surfen und jedes Java-Applet, auf das Sie jemals gestoßen sind, ohne Sicherheitsprobleme ausführen. Nun, solange die Java-Sandbox keine Sicherheitslücken aufweist.

Eine Alternative zum Sandkasten:

Authentifizierung durch Codesignatur

ActiveX ist eine weitere hochkarätige Form von ausführbaren Inhalten. ActiveX wurde von Microsoft gefördert und von Fachleuten für Computersicherheit kritisiert, die den Sicherheitsansatz als mangelhaft ansehen. Im Gegensatz zur Java-Sicherheitssituation, in der ein Applet durch die Softwaresteuerung in den möglichen Funktionen eingeschränkt wird, unterliegt ein ActiveX-Steuerelement nach dem Aufrufen keinen Einschränkungen hinsichtlich seines Verhaltens. Das Ergebnis ist, dass Benutzer von ActiveX sehr vorsichtig sein müssen, um nur vollständig vertrauenswürdigen Code auszuführen. Java-Benutzer hingegen haben den Luxus, nicht vertrauenswürdigen Code ziemlich sicher auszuführen.

Der ActiveX-Ansatz basiert auf digitalen Signaturen, einer Art Verschlüsselungstechnologie, bei der beliebige Binärdateien von einem Entwickler oder Distributor "signiert" werden können. Da eine digitale Signatur spezielle mathematische Eigenschaften aufweist, ist sie unwiderruflich und nicht fälschbar. Das bedeutet, dass ein Programm wie Ihr Browser eine Signatur überprüfen kann, sodass Sie sicher sein können, wer für den Code bürgt. (Zumindest ist das die Theorie. Im wirklichen Leben sind die Dinge etwas mehrdeutiger.) Besser noch, Sie können Ihren Browser anweisen, immer Code zu akzeptieren, der von einer Partei unterzeichnet wurde, der Sie vertrauen, oder Code, der von einer Partei, die Sie vertrauen, signiert hat, immer abzulehnen Vertraue nicht.

Eine digitale Signatur enthält viele Informationen. Beispielsweise kann es Ihnen sagen, dass Code, obwohl er von einer Site, der Sie nicht vertrauen, neu verteilt wird, ursprünglich von jemandem geschrieben wurde, dem Sie vertrauen. Oder es kann Ihnen sagen, dass, obwohl der Code von jemandem geschrieben und verteilt wurde, den Sie nicht kennen, Ihr Freund den Code unterschrieben hat, um zu bestätigen, dass er sicher ist. Oder es sagt Ihnen einfach, welcher der Tausenden von Benutzern bei aol.com den Code geschrieben hat.

(Weitere Informationen zu digitalen Signaturen, einschließlich fünf Schlüsseleigenschaften, finden Sie in der Seitenleiste.)

Die Zukunft ausführbarer Inhalte: Verlassen der Sandbox

Machen digitale Signaturen ActiveX sicherheitsrelevanter als Java? Wir glauben nicht, insbesondere angesichts der Tatsache, dass die Funktion für digitale Signaturen jetzt in Javas JDK 1.1.1 verfügbar ist (zusammen mit anderen Sicherheitsverbesserungen). Das bedeutet, dass Sie in Java alles erhalten, was ActiveX aus Sicherheitsgründen tut, sowie die Möglichkeit, nicht vertrauenswürdigen Code ziemlich sicher auszuführen. Die Java-Sicherheit wird in Zukunft durch eine flexible, fein abgestimmte Zugriffskontrolle noch weiter verbessert. Laut Li Gong, JavaSofts Java-Sicherheitsarchitekt, ist die Veröffentlichung in JDK 1.2 geplant. Eine bessere Zugriffskontrolle wird auch in der nächsten Runde von Browsern, einschließlich Netscape Communicator und MicroSoft Internet Explorer 4.0, Eingang finden.

In Verbindung mit der Zugriffskontrolle können Applets durch die Codesignatur die Sicherheits-Sandbox schrittweise verlassen. Beispielsweise kann ein Applet, das für die Verwendung in einer Intraneteinstellung entwickelt wurde, lesen und in eine bestimmte Unternehmensdatenbank schreiben, sofern es vom Systemadministrator signiert wurde. Eine solche Lockerung des Sicherheitsmodells ist wichtig für Entwickler, die darauf aus sind, dass ihre Applets mehr tun. Das Schreiben von Code, der innerhalb der strengen Beschränkungen der Sandbox funktioniert, ist ein Schmerz. Der ursprüngliche Sandkasten ist sehr restriktiv.

Letztendlich werden Applets unterschiedliche Vertrauensstufen gewährt. Da dies eine Zugriffskontrolle erfordert, sind derzeit keine Vertrauensschattierungen verfügbar, obwohl die Codesignatur aktiviert ist. Nach dem derzeitigen Stand von JDK 1.1.1 sind Java-Applets entweder vollständig vertrauenswürdig oder nicht vertrauenswürdig. Ein als vertrauenswürdig gekennzeichnetes signiertes Applet darf die Sandbox vollständig verlassen. Ein solches Applet kann alles und hat keine Sicherheitsbeschränkungen.

Das Hauptproblem bei Javas Sicherheitsansatz besteht darin, dass er kompliziert ist. Komplizierte Systeme weisen tendenziell mehr Mängel auf als einfache Systeme. Sicherheitsforscher, insbesondere das Secure Internet Programming-Team von Princeton, haben in früheren Versionen der Sandbox mehrere schwerwiegende Sicherheitslücken festgestellt. Viele dieser Fehler waren Implementierungsfehler, aber einige waren Spezifikationsfehler. Glücklicherweise haben JavaSoft, Netscape und Microsoft solche Probleme sehr schnell behoben, wenn sie entdeckt wurden. (Klare und vollständige Erklärungen zu den Sicherheitslücken von Java finden Sie in Kapitel 3 unseres Buches.)

Erst kürzlich wiesen Sun-Vermarkter (manchmal auch Evangelisten genannt) schnell darauf hin, dass seit geraumer Zeit keine neuen Mängel mehr entdeckt worden waren. Sie nahmen dies als Beweis dafür, dass Java nie wieder unter Sicherheitsproblemen leiden würde. Sie sprangen die Waffe.

Das Code-Signing-Loch: Java häutet sich das Knie

Das Signieren von Code ist kompliziert. Wie beim ursprünglichen Sandbox-Modell gibt es beim Entwerfen und Implementieren eines Codesignatursystems viel Raum für Fehler. Die jüngste Lücke war ein ziemlich einfaches Problem bei der Implementierung der Java- ClassKlasse, wie sowohl auf der Princeton-Site als auch auf der JavaSoft-Sicherheitssite erläutert wurde. Insbesondere gibt die Methode Class.getsigners()ein veränderbares Array aller dem System bekannten Unterzeichner zurück. Es ist möglich, dass ein Applet diese Informationen missbraucht. Das Update war so einfach wie die Rückgabe nur einer Kopie des Arrays und nicht des Arrays selbst.

Stellen Sie sich eine Situation vor, in der einem Entwickler, Alice, keine Sicherheitsberechtigung für das System eines Webbenutzers gewährt wurde. Im Gegensatz zu der ursprünglichen JavaSoft-Aussage zu dem Fehler kann Alice dem System völlig unbekannt sein. Mit anderen Worten, dem von Alice signierten Code wird nicht mehr vertraut als dem üblichen Applet von der Straße. Wenn der Webbenutzer (mit dem HotJava-Browser - derzeit das einzige kommerzielle Produkt, das JDK 1.1.1 unterstützt) ein von Alice signiertes Applet lädt, kann dieses Applet weiterhin aus der Sandbox treten, indem es die Lücke ausnutzt.

Die Tatsache, dass das System nicht den öffentlichen Schlüssel von Alice in seiner Datenbank haben muss, ist wichtig. Dies bedeutet, dass Alice jeder beliebige Angreifer sein kann, der weiß, wie man ein Applet mit einer völlig zufälligen Identität signiert. Das Erstellen einer solchen Identität ist einfach, ebenso wie das Signieren eines Applets mit dieser Identität. Dies macht das Loch in der Tat sehr ernst.

Das Loch ermöglicht es Alices Angriffs-Applet, die Vorstellung des Systems zu ändern, wer es signiert hat. Dies ist besonders schlimm, wenn Alice nicht das Privileg erhält, außerhalb der Sandbox zu laufen, Bob jedoch. Das Applet von Alice kann den getsigners()Aufruf verwenden, um die Berechtigungsstufe so zu ändern, dass alle Berechtigungen von Bob enthalten sind. Das Applet von Alice kann die maximale Anzahl verfügbarer Berechtigungen erhalten, die jedem dem System bekannten Unterzeichner gewährt werden .

Wenn Sie die Signatur- / Privilegienidentitäten mit Mänteln in einem Schrank vergleichen, kann Alices Angriffs-Applet jeden Mantel anprobieren und verschiedene unzulässige Dinge versuchen, bis es herausfindet, welche der Mäntel "magisch" sind, und ihm erlaubt, Privilegien zu erlangen. Wenn ein magischer Mantel entdeckt wird, kann Alices Applet aus dem Sandkasten treten und Dinge tun, die nicht erlaubt sein sollten. Das Anprobieren von Mänteln ist so einfach wie das Ausprobieren eines unzulässigen Anrufs und das Beobachten, was passiert.