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 Github Repositories Gitlab Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Aviator + Websockets

    15.06.2019

    Nachdem ich in den letzten Wochen und Monaten meine Zeit und Energie in die sQLshell gesteckt habe - was sowohl Bugfixing als auch neue Features betraf - habe ich nun endlich die Zeit gefunden, ein bereits lange überfälliges Feature an dWb+ und speziell am aviator zu implementieren.

    Weiterlesen...

Neueste Artikel

  • Neue Version plantumlinterfaceproxy napkin look

    Es gibt eine neue Version des Projektes plantumlinterfaceproxy - Codename napkin look.

    Weiterlesen...
  • Apache HTTPCore5 funktioniert nicht mit Docker

    Ich habe neulich drei Stunden meines Lebens verschwendet weil ich unbedingt die neueste Version der HTTPCore5 Library von Apache einsetzen wollte.

    Weiterlesen...
  • Entwurfsmodus für beliebige SVG Graphiken

    Nachdem ich in der Vergangenheit immer wieder Weiterentwicklungen der Idee vorgestellt habe, Graphiken mit dem Computer so zu ezeugen dass sie eine gewisse "handgemachte" Anmutung haben, habe ich nunmehr die durchschlagende Idee gehabt:

    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, muß 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 GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.