Minimierung von Angriffsoberflächen in Java

vorhergehende Artikel in: Java Software-Test Security
09.03.2024

Ich habe in einem früheren Artikel darauf hingewiesen, dass Java (17) und Python (3.10) sich bei der Validierung von x509-Zertifikaten ein wenig unterscheiden. Einer der Unterschiede ist die Schwelle, ab der Schlüssel wegen zu geringer Länge als unsicher bewertet und die damit verbundenen Zertifikate abgelehnt werden.

Dabei ging es um RSA-Schlüssel Python 3.10 weist solche mit einer Schlüssellänge von 1024 Bit zurück, während Java diese zunächst einmal zulässt.

Inzwischen ist ein wenig Zeit vergangen: Ich habe einen Vortrag zur Validierung von Zertifikaten beim 37C3 eingereicht, der aber abgelehnt wurde. Zu diesem Vortrag habe ich ein Repository erstellt, das dabei hilft, diverse Zertifikate mit kleineren und größeren Fehlern zu generieren, um die Validierung von Zertifikaten mit der in eigenen Projekten gewählten Sprache oder dem benutzten Framework zu testen.

In dem damit verbundenen Projekt zur Demonstration habe ich einige Java-Tests geschrieben, die als Illustration und Anregungen für eigene Testsuiten dienen können. Hier habe ich entsprechende Vorkehrungen getrofen, individuell zu kurze Schlüssel abweisen zu können. Zu Testzwecken mag das auch erst einmal akzeptabel sein - in Production-Code sollte man natürlich die von Java zur Verfügung gestellten Mittel benutzen...

In diesem Zusammenhang überlegte ich, ob es wohl möglich wäre, andere Angriffsoberflächen, die sich in Java verbergen ebenfalls zu verkleinern oder ganz auszuräumen. Ein Beispiel dafür sind Multimediadateien: Immer wieder finden sich in den Bibliotheken zur Verarbeitung solcher Dateien Lücken, die es erlauben, sie mit speziell dafür erstellten Multimediadateien anzugreifen. Auswirkungen sind dabei ganz verschieden und können mitunter auch sehr schlimm werden.

Java bedient sich diverser Methoden, Bilder zu laden. Dabei ist es so, dass Standard-Java-Programme die eingebauten Methoden nutzen, da sie für den Entwickler der Software so wenig Aufwand bedeuten: Er muss lediglich sagen, dass eine Datei geladen werden soll - Java sucht sich den passenden Codec und wendet ihn an. Wenn aber von vornherein klar ist, dass die Anwendung lediglich JPGs und PNGs verarbeiten soll - wieso sollten dann überhaupt Codecs für BMP oder GIF (oder andere) verfügbar sein?

Das Szenario hier ist, dass ein Angreifer eine Lücke im BMP-Codec ausnutzen will. Er speichert also ein Bild mit der Endung .jpg ab, das aber ein BMP ist, das er exakt so erzeugt hat, dass es die Lücke triggert. Java analysiert die Datei und findet heraus, dass der BMP-Codec gebraucht wird, wendet ihn an und - hey, presto! Das Opfer wurde erfolgreich attackiert!

Um dies zu verhindern, müsste es eine Möglichkeit geben, diese nicht benötigten Codecs zu deaktivieren oder man müsste eine Whitelisting Regel erstellen können, in der vermerkt ist, welche Codecs die Anwendung benutzen soll.

Diese Analyse bezieht sich nicht nur auf Multimedia Codecs, sondern auf alle Bereiche von Java, die mittels der ServiceProviderInfrastructure erweiterbar sind.

Dafür gibt es verschiedene Ansätze, die aber nur dazu taugen, bekannte Codecs oder andere Bibliotheken zu deaktivieren.

Diese helfen aber nicht vollständig gegen einen bösartigen Angreifer, da sie konfigurative Maßnahmen darstellen und zum Beispiel auf die Manifest-Dateien in JARs abzielen. Ein Angreifer kann aber diese Datei ändern und damit geht der vermeintliche Schutz ins Leere.

Der ServiceLoader bietet weitere Möglichkeiten wie etwa die Inspektion der verschiedenen Provider mittels der Methode stream() - sie erlaubt es zum Beispiel, die gefunden Implementationen auf vorhandene oder fehlende Annotations zu checken.

Auch das ist aber keine Komplettlösung, da ja - wie in unserem Beispiel der Multimedia-Codecs die Serviceprovider nicht unter unserer Kontrolle stehen und wir daher keine Annotations hinzufügen können - außerdem können Angreifer ja einfach ihre verseuchten Bibliotheken mit unseren Whitelisting-Annotations versehen.

Es existieren Stellen in Java, in denen SPI nicht automatisch aktiv ist - dazu zählt unter anderem die Lokalisierung.

Es existiert aber bisher meines Wissens keine Möglichkeit, SPI global abzuschalten und nur für bestimmte Services und ServiceProvider zu aktivieren.

Alle Artikel rss Wochenübersicht Monatsübersicht Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen Codeberg-Repositories findet man hier.