Es ist ein ziemlich altes Thema, aber immer noch auf dem neuesten Stand und bringt heutzutage überraschenderweise eine größere Wirkung. Wie Jon erwähnte, könnte es nur ein Fehler sein, den Javas Designer am Anfang gemacht haben. Aber ich würde es mir nicht vorstellen, bevor es Auswirkungen auf die Sicherheit haben kann.
Viele Programmierer kennen Apache Velocity, eine flexible und leistungsstarke Template-Engine. Es ist so leistungsfähig, dass es die Vorlage von Vorlagen mit einer Reihe benannter Objekte ermöglicht - streng genommen als Objekte aus der Programmiersprache (ursprünglich Java). Auf diese Objekte kann wie in der Programmiersprache innerhalb einer Vorlage zugegriffen werden, sodass beispielsweise die String-Instanz von Java mit all ihren öffentlichen Feldern, Eigenschaften und Methoden verwendet werden kann
$input.isEmpty()
Dabei ist die Eingabe ein String , läuft direkt über JVM und gibt true oder false an die Ausgabe des Velocity-Parsers zurück. So weit, ist es gut.
In Java erben jedoch alle Objekte von Object, sodass unsere Endbenutzer dies auch in die Vorlage einfügen können
$input.getClass()
um eine Instanz von String Class zu erhalten.
Und mit dieser Referenz können sie auch einen Aufruf statische Methode forName (String) auf diese
$input.getClass().forName("java.io.FileDescriptor")
Verwenden Sie einen beliebigen Klassennamen und verwenden Sie ihn für jedes Konto des Webservers (Verunstalten, DB-Inhalt stehlen, Konfigurationsdateien überprüfen, ...).
Dieser Exploit wird hier (in einem bestimmten Kontext) beschrieben: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py
Es wäre nicht möglich, wenn das Aufrufen statischer Methoden aus der Referenz auf die Instanz der Klasse verboten wäre.
Ich sage nicht, dass ein bestimmtes Programmierframework besser ist als das andere oder so, aber ich möchte nur einen Vergleich anstellen. Es gibt eine Portierung von Apache Velocity für .NET. In C # ist es nicht möglich, statische Methoden nur aus der Referenz der Instanz aufzurufen, was einen solchen Exploit nutzlos macht:
$input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
String hello = null; hello.valueOf(123);
funktioniert!