Mass Assignment: Funktionsweise und Schutz
Autor: Redaktion Domeny.ForSale Veröffentlicht
Kurz erklärt: Mass Assignment bezeichnet die automatische Zuweisung von Daten aus einer HTTP-Anfrage an Felder eines internen Objekts oder Datenbankmodells. Zur Sicherheitslücke wird dieses Verfahren, wenn die Anwendung dadurch auch Änderungen an Feldern zulässt, über die der Benutzer keine Kontrolle haben sollte – etwa an seiner Administratorrolle. Der Schutz besteht vor allem darin, erlaubte Felder ausdrücklich festzulegen und Berechtigungen auf dem Server zu prüfen.
Wie die automatische Feldzuweisung funktioniert
Eine Webanwendung empfängt Daten, die der Browser beispielsweise beim Speichern eines Profils übermittelt. Eine HTTP-Anfrage, also eine an den Server gesendete Nachricht, kann den Benutzernamen, die E-Mail-Adresse und weitere Werte enthalten. Der Server muss diese anschließend den entsprechenden Feldern in seinem Code zuweisen.
Mass Assignment ermöglicht diese Zuweisung in einem Schritt, ohne jeden Wert einzeln zuzuordnen. Der Mechanismus gleicht die Namen der empfangenen Felder mit den Eigenschaften des Objekts ab. Enthalten die Daten das Feld name, kann dessen Wert in die Eigenschaft name des Benutzerobjekts übernommen werden.
Diese Zuordnung wird auch als autobinding bezeichnet. Im Zusammenhang mit dieser Schwachstelle begegnet einem außerdem der Begriff object injection, der in anderen Sicherheitskontexten allerdings andere Mechanismen bezeichnen kann. Die automatische Zuordnung an sich ist kein Fehler: Problematisch wird sie, wenn der Server mehr Felder akzeptiert, als er sollte.
Einfaches Beispiel: Profil bearbeiten und Rolle ändern
Angenommen, ein Formular zur Profilbearbeitung erlaubt nur Änderungen am Anzeigenamen und an der E-Mail-Adresse. Die regulär an den Server gesendeten Daten sehen so aus:
{
"name": "Anna",
"email": "anna (at) example.com"
}
In der Datenbank besitzt das Konto jedoch weitere Eigenschaften. Neben Name und E-Mail-Adresse enthält es auch das Feld rolle, das die Berechtigungen des Benutzers bestimmt. Im Formular wird es nicht angezeigt, weil ein gewöhnlicher Benutzer es nicht ändern können sollte.
Angreifer müssen das Formular jedoch nicht verwenden. Sie können die gesendete Anfrage verändern und ein zusätzliches Feld einfügen:
{
"name": "Anna",
"email": "anna (at) example.com",
"rolle": "administrator"
}
Kopiert der Server alle empfangenen Eigenschaften ohne Einschränkung in das Benutzerkonto, kann er dabei auch die neue Rolle speichern. Verwendet das Berechtigungssystem dieses Feld, kann der Angreifer dadurch Administratorzugriff erlangen.
Ein Feld im Formular wegzulassen, ist keine Schutzmaßnahme. Welche Änderungen zulässig sind, muss der Server bestimmen – nicht die Darstellung der Seite oder der im Browser ausgeführte JavaScript-Code.
Welche Daten besonders gefährdet sind
Mass Assignment betrifft nicht nur Benutzerkonten. Das Risiko besteht überall dort, wo externe Daten automatisch in Objekte übernommen werden, die auch interne Eigenschaften enthalten.
Folgende Felder erfordern beispielsweise besondere Kontrolle:
eigentuemer_id– kann festlegen, wem ein Dokument oder eine Bestellung gehört;preis– kann den für einen Einkauf berechneten Betrag beeinflussen;zahlungsstatus– kann angeben, ob eine Bestellung bezahlt wurde;email_bestaetigt– kann darüber entscheiden, ob die Bestätigung der E-Mail-Adresse übersprungen wird.
Ein Kunde eines Onlineshops sollte beispielsweise die Produktkennung und die gewünschte Stückzahl übermitteln. Den Preis sollte der Server anhand seines eigenen Angebots ermitteln, statt den in der Anfrage angegebenen Wert ungeprüft zu übernehmen.
Nicht jedes zusätzliche Feld ermöglicht einen Angriff. Es muss akzeptiert, zugewiesen und auf eine Weise verwendet werden, die für das Verhalten der Anwendung relevant ist. Deshalb muss die Analyse den gesamten Datenfluss berücksichtigen, nicht nur den Inhalt des Formulars.
Wie sich Mass Assignment wirksam begrenzen lässt
Der grundlegende Schutz ist eine Liste erlaubter Felder: Der Server akzeptiert für einen bestimmten Vorgang ausschließlich die vom Entwickler festgelegten Eigenschaften. Bei einer gewöhnlichen Profilbearbeitung können das name und email sein, nicht aber rolle.
Das Vorgehen kann schematisch so aussehen:
erlaubte_felder = ["name", "email"]
profildaten = waehle_felder(anfragedaten, erlaubte_felder)
aktualisiere_profil(angemeldeter_benutzer, profildaten)
Dies ist Pseudocode zur Veranschaulichung des Prinzips, keine fertige Implementierung. Je nach Framework lassen sich die Einschränkungen im Zuordnungsmechanismus, in einem Validator oder in einem separaten Eingabeobjekt festlegen, das häufig als DTO bezeichnet wird. Ein solches Objekt beschreibt die für einen konkreten Vorgang zulässigen Daten, statt den gesamten Datenbankdatensatz abzubilden.
Eine reine Formatprüfung reicht nicht aus. Der Wert administrator kann eine gültige Rollenbezeichnung sein, ohne dass ein gewöhnlicher Benutzer berechtigt ist, diese Rolle festzulegen. Zusätzlich ist daher eine Autorisierung erforderlich: Es muss geprüft werden, ob die betreffende Person die konkrete Änderung vornehmen darf.
Bei einer Liste verbotener Felder wird leichter etwas übersehen: Wird dem Modell eine neue Eigenschaft hinzugefügt, muss man daran denken, sie zu sperren. Eine Liste erlaubter Felder gibt neue Eigenschaften hingegen nicht automatisch frei. Das genaue Verhalten und die standardmäßigen Schutzmaßnahmen des verwendeten Frameworks sollten anhand seiner offiziellen Dokumentation überprüft werden.
So prüfst du deine eigene Anwendung
Teste ausschließlich dein eigenes System oder eine Umgebung, für die du eine entsprechende Erlaubnis hast. Bereite für die Profilbearbeitung eine Anfrage mit gültigen Daten vor und ergänze anschließend ein Feld, das der Benutzer nicht ändern dürfen sollte.
Prüfe nicht nur die Antwort des Servers, sondern auch die gespeicherten Daten und die tatsächlichen Berechtigungen des Kontos. Eine sichere Implementierung sollte die unzulässige Änderung ablehnen oder das zusätzliche Feld ignorieren, ohne den geschützten Wert zu verändern.
Sieh dir zunächst die Stellen an, an denen sämtliche Daten einer Anfrage direkt an Methoden zum Erstellen oder Aktualisieren von Datensätzen übergeben werden. Halte für jede dieser Stellen die erlaubten Felder fest und ergänze einen Test, der bestätigt, dass sich die übrigen Felder nicht ändern lassen.
Siehe auch: Was ist Path Traversal?
