Binäre Serialisierung – Umwandlung eines Objekts in eine Folge von Binaerbytes

Eine besondere Art der binären Serialisierung ist die Umwandlung eines Objekts in eine Folge von Bytes.

Damit wird die Konvertierung eines Objekts in einen Byte-Stream ermöglicht, um das Objekt zu speichern, in den Arbeitsspeicher, eine Datenbank oder eine Datei zu übertragen.

Serialisierung von Daten in der Informatik

Serialisierung von Daten in der Informatik

Die Daten-Serialisierung ist somit ein Konzept und Design Pattern für Programmiersprachen.

Wie funktioniert das serialisieren von Daten?

Zum Serialisieren wird ein Objekt in einem Stream von Daten überführt, der die Daten enthält.

Der Data Stream kann auch Informationen zum Objekttyp enthalten, z. B. zur Version, Datentyp und zum Assemblynamen.

Aus diesem Datenfluss kann das Objekt in einer Datenbank, einer Datei oder einem Arbeitsspeicher gespeichert werden.

Wozu dient die Serialisierung von Daten?

Hauptzweck der Serialisierung ist es, den Zustand eines Objekts zu speichern, um es bei Bedarf neu erstellen zu können.

Somit kannst Du als Entwickler*in jederzeit den Zustand eines Objekts speichern und das Objekt bei Bedarf neu erstellen und folgenden Aktionen ausführen:

  • Senden des Objekts per Remote-Verbindung, z.B. per Webdienst
  • Objekte von einer Domäne zu einer anderen transferieren
  • ein Objekt geschützt über eine Firewall als JSON– oder XML-Zeichenfolge übermitteln
  • Verwalten von Sicherheits- und benutzerspezifischen Informationen über Anwendungen
Warum die Binaer Serialisierung Sicherheitsrisiken eröffnet

Warum die Binaer Serialisierung Sicherheitsrisiken eröffnet

Binär-Serialisierung und XML-Serialisierung

Auch wenn eine Programmiersprache Klassen für die binäre Serialisierung oder zur XML-Serialisierung enthält, sind diese mit äußerster Vorsicht zu verwenden!

Warning

Warning zur Anwendung der Serialisierung in ungeschützten Bereichen

Warum die Binär-Serialisierung Sicherheitsrisiken eröffnet

Die binäre Serialisierung verwendet zum Generieren einer kompakten Serialisierung die binäre Codierung für den Speicher oder für Socket-basierte Netzwerkstreams.

Bei der binären Serialisierung werden alle Member des Objekts – einschließlich derjenigen mit zugriffs- also schreibgeschützten Attributen – serialisiert. Somit verbessert ein Serialisieren zwar immer auch die Performance eines Streams, ABER das in einer Anwendung implementierte Zugriffs- und Rechte-Management wird außer Kraft gesetzt.

Sicherheitsaspekte bei der Binär-Serialisierung

Die Binär-Serialisierung, bei der Datenstrukturen in ein binäres Format umgewandelt werden, bringt spezifische Sicherheitsrisiken mit sich, die sorgfältig berücksichtigt werden müssen.

Risiken der Binär-Serialisierung

  1. Unautorisierte Codeausführung: Wenn ein Angreifer manipulierte Objekte serialisieren kann, die dann deserialisiert werden, könnte dies zur Ausführung schädlichen Codes führen.
  2. Datenlecks: Sensible Informationen könnten versehentlich in den serialisierten Daten eingeschlossen und dann offengelegt werden.
  3. Replay-Angriffe: Ohne angemessene Sicherheitsmaßnahmen könnten serialisierte Daten abgefangen und wiederverwendet werden, um unbefugten Zugriff oder Aktionen zu bewirken.
  4. Injections: Schlecht validierte Eingaben könnten zu Injection-Angriffen führen, bei denen unerwünschte Daten in den Deserialisierungsprozess eingespeist werden.

Best Practices zum Schutz:

  1. Validierung der Eingabe: Stellen Sie sicher, dass alle eingehenden Daten vor der Deserialisierung validiert werden, um bösartige Daten zu erkennen und zu verhindern.
  2. Minimierung der Verwendung: Beschränken Sie die Verwendung der Binär-Serialisierung auf vertrauenswürdige Datenquellen und vermeiden Sie es, wo möglich.
  3. Verwendung sicherer Bibliotheken: Wählen Sie Bibliotheken und Tools, die für ihre Sicherheitsmaßnahmen bekannt sind, und halten Sie sie aktuell.
  4. Sicherheitsaudits und Tests: Führen Sie regelmäßige Sicherheitsüberprüfungen und Penetrationstests durch, um Schwachstellen zu identifizieren und zu beheben.
  5. Objekt-Level-Zugriffskontrolle: Implementieren Sie Zugriffskontrollen, die definieren, welche Objekte deserialisiert werden dürfen und welche nicht.

Werkzeuge und Bibliotheken für Serialisierung

Verschiedene Programmiersprachen bieten unterschiedliche Tools und Bibliotheken für die Serialisierung. Hier sind einige gängige Beispiele:

Python:

  • Pickle: Eine eingebaute Bibliothek für die Serialisierung und Deserialisierung von Python-Objekten. Achtung: pickle ist nicht sicher gegen fehlerhafte oder bösartige Daten und sollte daher nicht für Daten verwendet werden, die von einer unbekannten Quelle stammen.
  • JSON: Die json Bibliothek wird für die Arbeit mit JSON-Daten verwendet, eine textbasierte und sprachunabhängige Darstellung von Objekten.

Java:

  • Java Serialization API: Ermöglicht die Serialisierung von Objekten in einen Byte-Stream, der dann in Dateien, Datenbanken oder über Netzwerke übertragen werden kann.
  • Jackson und Gson: Beliebte Bibliotheken für die Arbeit mit JSON, bieten sowohl Serialisierung als auch Deserialisierung an.

JavaScript:

  • JSON.stringify/JSON.parse: Native Methoden in JavaScript für die Serialisierung und Deserialisierung von Objekten in und aus JSON.
  • BSON: Eine binäre Darstellung von JSON-ähnlichen Dokumenten, oft verwendet in Verbindung mit MongoDB.

Während die Serialisierung ein mächtiges Werkzeug in der Softwareentwicklung ist, bringt sie bei unsachgemäßer Handhabung erhebliche Sicherheitsrisiken mit sich, insbesondere bei der Binär-Serialisierung.

Ein tiefes Verständnis der Risiken und der Implementierung von Best Practices ist entscheidend, um diese zu mitigieren. Gleichzeitig ist die Auswahl der richtigen Werkzeuge und Bibliotheken für die Serialisierung in Ihrer spezifischen Programmiersprache entscheidend, um sowohl die Effizienz als auch die Sicherheit Ihrer Anwendungen zu gewährleisten.

Was Du unbedingt bei der XML-Serialisierung beachten solltest

Bei der XML-Serialisierung sollten öffentliche Daten-Felder, Eigenschaften eines Objekts, Objekt-Parameter und Rückgabewerte von Methoden in einen XML-Stream serialisiert werden, der dem offiziellen XML Schema Definition entspricht.

Die XML-Serialisierung führt zu stark typisierten Klassen mit öffentlichen Eigenschaften und Feldern, die in XML konvertiert werden.

Für die Binär- oder XML-Serialisierung benötigst Du:

  1. das zu serialisierende Objekt
  2. einen Stream mit dem serialisierten Objekt
  3. eine systemspezifische Laufzeit-Instanz zur Formatierung des Objekts

Markiere Attribute in Objekten gezielt als nicht serialisierbar um zu verhindern, dass sensible Daten serialisiert werden.

Auch wenn ein Feld eines serialisierbaren Typs einen Zeiger, ein Handle oder eine andere Datenstruktur enthält und somit für eine bestimmte Umgebung spezifisch ist, so dass dieses Feld in keiner anderen Umgebung sinnvoll wiederhergestellt werden kann, solltest Du den Typ als nicht serialisierbar markieren.

Hier sind detaillierte Beispiele für die Implementierung der Serialisierung in verschiedenen Programmiersprachen:

 

Python – JSON-Serialisierung:

import json

# Ein Dictionary in Python
data = {
'name': 'John Doe',
'age': 29,
'is_employee': True,
'languages': ['English', 'French'] }

# Serialisierung: Konvertieren des Dictionaries in einen JSON-String
json_string = json.dumps(data)

# Gibt den JSON-String aus
print(json_string)

# Deserialisierung: Konvertieren des JSON-Strings zurück in ein Python-Dictionary
parsed_data = json.loads(json_string)

# Gibt das wiederhergestellte Dictionary aus
print(parsed_data)

Java – Java-Objekt-Serialisierung

import java.io.*;

public class User implements Serializable {
private String name;
private int age;

// Konstruktoren, Getter und Setter hier…

public static void main(String[] args) {
User user = new User("John Doe", 29);

// Serialisierung
try {
FileOutputStream fileOut = new FileOutputStream("user.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(user);
out.close();
fileOut.close();
System.out.println("Serialized data is saved in user.ser");
} catch (IOException i) {
i.printStackTrace();
}

// Deserialisierung
User deserializedUser = null;
try {
FileInputStream fileIn = new FileInputStream("user.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
deserializedUser = (User) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("User class not found");
c.printStackTrace();
return;
}

System.out.println("Deserialized User...");
System.out.println("Name: " + deserializedUser.getName());
System.out.println("Age: " + deserializedUser.getAge());
}
}

JavaScript – JSON-Serialisierung

// Ein Objekt in JavaScript
let data = {
name: "Jane Doe",
age: 34,
is_employee: false,
languages: ["Spanish", "German"] };

// Serialisierung: Konvertieren des Objekts in einen JSON-String
let jsonString = JSON.stringify(data);

console.log(jsonString); // Gibt den JSON-String aus

// Deserialisierung: Konvertieren des JSON-Strings zurück in ein Objekt
let parsedData = JSON.parse(jsonString);

// Gibt das wiederhergestellte Objekt aus
console.log(parsedData);

Diese Codebeispiele zeigen Dir anschaulich, wie die Serialisierung in Python, Java und JavaScript umgesetzt wird.

In Python und JavaScript wird meist JSON für die Serialisierung verwendet, da es nativ unterstützt wird und die Daten leicht zwischen verschiedenen Systemen übertragen werden können.

Java bietet eine eingebaute Möglichkeit zur Serialisierung von Objekten, die besonders nützlich ist, wenn Objekte über ein Netzwerk gesendet oder in Dateien gespeichert werden müssen.

In jedem Fall ist es wichtig, dass Du die Sicherheitsaspekte der Serialisierung zu berücksichtigst, insbesondere wenn Du mit externen Daten arbeitest.