Datenklau leicht gemacht: Unsichere Objektreferenzen

Diese Woche wurde bekannt, dass tausende Kundendatensätze im Geschäftskundenbereich der Deutschen Bahn abgegriffen werden konnten. Grund sind unsichere direkte Objektreferenzen.

Was ist passiert?

An Kunden wurde eine URL mit einer Firmen-ID gesendet. Auf der Seite waren Kundendaten zu sehen. Diese Firmen-IDs konnte man durchiterieren und erhielt die Daten anderer Kunden zu sehen. Die Journalisten von CORRECTIV.RUHR schieben ein kleines Script, welches diesen Prozess automatisiert. So war es ihnen möglich in 45 Minuten etwa 10.000 Datensätze abzugreifen.

Angreifer erhielten also ohne Autentifizierung direkten Zugang zu fremden Daten. Dies war in diesem Fall auch mehr oder weniger erwünscht, denn der Mail-Empfänger sollte mit einem Klick in der Lage sein seine Daten einzusehen.

Ein Beispiel für unsichere direkte Objektreferenzen

$sql = "SELECT * FROM geschaeftskunden WHERE id = ?";
$statement = $db->prepare($sql);
$statement->execute(array($_GET['firmenid']));
$firma = $statement->fetch();

Ein Aufruf wie würden eine direkt Objektreferenz ermöglichen:

http://schlechter.zug/geschaeftskunden/?firmenid=[NichtMeineId]

Was kann ich tun?

Es kommt sehr auf den Use-Case an, wie die Lösung aussieht. Muss der Kunde sich zunächst Authentifizieren, so muss nachgesehen werden, ob der User Zugang zum angefragten Objekt haben darf.

Im genannten Beispiel verhält sich das anders. Hier soll eine schnelle, direkte Möglichkeit zur Betrachtung der Kundendaten geboten werden. Ich sehe hier drei Möglichkeiten, aber alle drei brechen die Möglichkeit der Iteration:

  1. Die “firmenid” mit einem geheimen Schlüssel ver- und entschlüsseln.
  2. Eine weitere nicht-numerische ID kann in die Datenbank einfügen und diese für den Zugang nutzen. Zum Beispiel UUIDs.
  3. Zugangstokens erstellen, welche nicht-numerische, nicht iterierbare IDs besitzen. Vorteil: Eine Zeitliche Befristung wäre ohne weiteres Möglich.

Zu Möglichkeit 1:

$pw = "ffio54klfds08§98";
$firmenId = 123;
$mailFirmenId = openssl_encrypt($firmenId, 'aes-256-cbc', $pw);

// Mailversand mit ^- $mailFirmenId

// -------- Auf der verlinkten Seite:
$mailFirmenId = $_GET['firmenid'];
$firmenId = openssl_decrypt($mailFirmenId, 'aes-256-cbc', $pw);
$sql = "SELECT * FROM geschaeftskunden WHERE id = ?";
$statement = $db->prepare($sql);
$statement->execute(array($firmenId));
$firma = $statement->fetch();

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert