2016-09-30 17 views
3

In meinem Code rufe ich die getObject() -Methode von einem ObjectMessage-Objekt auf, das von einer JMS-Warteschlange empfangen wird. Fortify-Bericht beschwert sich über diese getObject() -Methode mit einem Fehlernamen wie diesem Dynamic Code Evaluation: Unsafe Deserialization. Grundsätzlich heißt es, ich sollte nicht vertrauenswürdige Daten deserialisieren, ohne den Inhalt des Objektstroms zu validieren. Unten ist der Code. Wie und welche Methoden sollte ich verwenden, um diesen Fortify-Bericht Fehler bitte loszuwerden.So validieren Sie ein Objekt vor der Deserialisierung

if (message instanceof ObjectMessage) { 
    ObjectMessage objMessage = (ObjectMessage) message; 
    Object objReportMessage = objMessage.getObject(); 
.... 

Hier ist das Fortify-Problem mit Empfehlungen gemeldet. Dann zeigt dieser Fehler auf den Code oben in der Zeile objMessage.getObject();

Dynamic Code Bewertung: Unsichere Deserialisierung (1 Ausgabe)

Abstrakt Deserialisieren benutzergesteuerte Objekt-Streams während der Laufzeit kann es Angreifern ermöglichen, beliebigen Code auf dem Logik Missbrauch Anwendung Server auszuführen oder zu Denial führen von Bedienung.

Erklärung Java Serialisierung dreht Objektgraphen in Bytestreams die Objekte selbst und die erforderlichen Metadaten enthalten sie aus dem Bytestrom zu rekonstruieren. Entwickler können bei der Deserialisierung von Java-Objekten benutzerdefinierten Code zur Unterstützung von erstellen, wobei sie sogar die deserialisierten Objekte durch andere Objekte oder Proxies ersetzen können. Der angepasste Deserialisierungsprozess findet während der Objekte Rekonstruktion statt, bevor die Objekte an die Anwendung zurückgegeben und in erwartete Typen umgewandelt werden. Zu der Zeit Entwickler versuchen, einen erwarteten Typ zu erzwingen, Code wurde möglicherweise bereits ausgeführt. Benutzerdefinierte Deserialisierungsroutinen sind in den serialisierbaren Klassen definiert, die im Laufzeitklassenpfad vorhanden sein müssen und vom Angreifer nicht injiziert werden können. Daher hängt die Ausnutzbarkeit dieser Angriffe von den in der Anwendungsumgebung verfügbaren Klassen ab. Leider können gängige Klassen von Drittanbietern oder sogar JDK-Klassen missbraucht werden, um JVM-Ressourcen auszuschöpfen, schädliche Dateien bereitzustellen oder willkürlichen Code auszuführen. Bestimmte Protokolle verwenden die Java-Serialisierung hinter den Kulissen in der Transportschicht. RMI und JMX sind Beispiele für diese Protokolle.

Beispiel 1: Hier ist ein Beispiel für eine RMI-Schnittstelle, die öffentlich verfügbar gemacht werden kann und Methoden mit einen oder mehrere Parameter enthält. Wenn diese Methoden remote aufgerufen werden, werden die Argumente auf dem Server deserialisiert, sodass Angreifer bösartige Objektdiagramme einfügen können.

public interface MyService extends java.rmi.Remote { 
public Object doSomething (Object arg0) throws RemoteException; 
public Object doSomethingElse (Object arg0, Object arg1) throws 
RemoteException; 
... 
} 

Beispiel 2: JMX MBeans auch Aufruf Argumente verwenden Java Serialisierung zu übertragen. Im folgenden Beispiel werden die Klassenmethoden MyManagedBean für Clients verfügbar gemacht.

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
ObjectName name = new ObjectName("com.example:type=MyManagedBean"); 
MyManagedBean mbean = new MyManagedBean(); 
mbs.registerMBean(mbean, name); 

Empfehlung Wenn möglich, deserialisieren nicht nicht vertrauenswürdige Daten, ohne den Inhalt des Objekts Strom zu validieren. Um Klassen zu validieren, die deserialisiert werden, sollte das Look-Ahead-Deserialisierungsmuster verwendet werden. Der Objektstrom enthält zuerst die Klassenbeschreibungsmetadaten und dann die serialisierten Bytes ihrer Mitgliedsfelder. Der Java-Serialisierungsprozess ermöglicht es Entwicklern, die Klassenbeschreibung zu lesen und zu entscheiden, ob die Deserialisierung des Objekts fortgesetzt oder abgebrochen werden soll ( ). Um dies zu tun, ist es notwendig, Unterklasse java.io.ObjectInputStream und bieten eine benutzerdefinierte Implementierung der resolveClass (ObjectStreamClass desc) -Methode, wo Klassenüberprüfung und Verifizierung 29.09.2016, 17.09 Uhr Copyright 2015 Hewlett Packard Enterprise Development LP 13 stattfinden. Es gibt bereits vorhandene Implementierungen des Look-Ahead-Musters, die leicht verwendet werden können, z. B. Apache Commons IO (org.apache.commons.io.serialization.ValidatingObjectInputStream). Verwenden Sie immer einen strengen Whitelist-Ansatz, um erwartete Typen nur zu deserialisieren. Ein Blacklist-Ansatz ist nicht empfohlen, da Angreifer viele verfügbare Gadgets verwenden können, um die Blacklist zu umgehen. Beachten Sie auch, , dass, obwohl einige Klassen, um Codeausführung zu erreichen, öffentlich bekannt sind, gibt es andere, die unbekannt oder nicht bekannt sind, so dass eine Whitelist-Ansatz immer bevorzugt werden. Jede Klasse, die in der Whitelist zulässig ist, sollte geprüft werden, um sicherzustellen, dass die Deserialisierung sicher ist. Um Denial-of-Service-Angriffe zu vermeiden, empfiehlt es sich, die Methode resolveObject (Object obj) zu überschreiben, um zu ermitteln, wie viele Objekte deserialisiert werden, und die Deserialisierung abzubrechen, wenn ein Schwellenwert überschritten wird. Wenn die Deserialisierung in einer Bibliothek oder einem Framework stattfindet (z. B. bei Verwendung von JMX, RMI, JMS, HTTP Invokern), ist die obige Empfehlung nicht nützlich, da sie vom Entwickler nicht kontrolliert werden kann. In diesen Fällen können Sie sicherstellen, dass diese Protokolle die folgenden Anforderungen erfüllen: - Nicht öffentlich zugänglich gemacht. - Authentifizierung verwenden. - Verwenden Sie Integritätsprüfungen. - Verwenden Sie die Verschlüsselung. Darüber hinaus bietet HPE Security Fortify Runtime Sicherheitskontrollen, die jedes Mal erzwungen werden müssen, wenn die -Anwendung eine Deserialisierung von einem ObjectInputStream durchführt und dabei sowohl den Anwendungscode als auch den Bibliotheks- und Framework-Code vor dieser Art von Angriff schützt.

+0

Sie können nicht, und die Nachricht kann das nicht ernst meinen. – EJP

+0

Ja, ich konnte nichts hilfreiches online finden, vielleicht verstehe ich es falsch oder der Fortify-Bericht erkannte das Problem nicht richtig. Ich habe gerade den Post bearbeitet und das Problem aus dem Fortify-Bericht hinzugefügt, können Sie mir bitte helfen, einen Blick darauf zu werfen? Vielen Dank. –

Antwort

3

Werfen Sie einen Blick auf die ValidatingObjectInputStream. Im Grunde nehmen Sie eine Whitelist für die Klassen vor, die Sie deserialisieren dürfen (Sie sollten diese basierend auf den Informationen kennen, die Sie ziehen). Der Validator überprüft dann die Metadaten auf die serialisierten Daten und lehnt alle Klassen ab, die nicht in der Whitelist enthalten sind.

3

Wenn Sie den Tippteil aus den Empfehlungen betrachten, heißt es, dass das Problem auch dann gemeldet wird, wenn ein Look-Ahead-ObjectInputStream implementiert ist. Daher, selbst wenn Sie das Problem beheben konnten, werden Sie nicht das Finden loswerden.

Es sieht jedoch so aus, als ob Ihr Code JMS verwendet und mit JMS steuern Sie die Deserialisierung nicht. Dies wird durch die Empfehlungen erkannt Sie kopiert und eingefügt:

Wenn Deserialisierung erfolgt in einer Bibliothek oder einem Rahmen (zB bei Verwendung von JMX, RMI, JMS, HTTP Invoker) die oben genannte Empfehlung nicht sinnvoll ist, da sie über das ist Entwickler Kontrolle. In diesen Fällen möchten Sie möglicherweise sicherstellen, dass diese Protokolle die folgenden Anforderungen erfüllen:

  • Nicht öffentlich zugänglich gemacht.
  • Authentifizierung verwenden.
  • Verwenden Sie Integritätsprüfungen.
  • Verschlüsselung verwenden.
  • Daher ist Ihre wahre Lösung, um sicherzustellen, dass diese vier Aufzählungspunkte befolgt werden. Sie müssen Ihre Verbindung recherchieren und je nach Ihren Anforderungen und Einschränkungen ist dies möglicherweise nicht möglich.

    Verwandte Themen