Inhaltstypen
Pages
Posts
06.08.2014

Sicheres Data Binding im Play Framework

Ausgangslage

Mit dem Java Play Framework lassen sich Formular-Übermittlungen elegant im zugrunde liegenden Datenmodell speichern. Dazu wird ein Form-Objekt aus dem eingehenden Request erstellt, daraus die Entity geholt und gespeichert, wie im nachfolgenden Beispiel (aus der Play-Beispiel App “Computer Database”) gezeigt.

Das Problem

Auf den ersten Blick mag man versucht sein – wie im von Play mitgelieferten Beispiel auch suggeriert – direkt seine Modelle so zu aktualisieren. Dies führt aber natürlich zu einem grossen Sicherheitsloch: Das Mapping von Formularfeld zu Entity-Attribut erfolgt automatisch anhand des Namens. Durch Veränderung der GET/POST-Daten (Parameter Tampering) kann der Angreifer jedes beliebige Feld der hinterlegten Entität verändern, auch wenn er per Formular darauf keinen Zugriff hätte.

Übliche Lösungen

Man erstellt eine für jedes Formular spezifische Formular-Klasse, welche die erlaubten Felder definiert und das Mapping auf die Model-Klasse übernimmt. Oder man verwendet den allowedFields Parameter in bindFromRequest() um die erlaubten Felder einzuschränken.

Beide Methoden erfordern, dass die editierbaren Felder explizit doppelt definiert werden: Im Formular sowie in der Form-Klasse (oder dem allowedFields Parameter). Das kann bei umfangreichen und oft ändernden Formularen recht umständlich und fehleranfällig werden. Auch, weil standardmässig nicht erkannte Felder still ignoriert werden – was beim Debugging nicht gerade hilfreich ist.

Die SecureForm

Wir haben mit dem SecureForm Projekt einen weiteren Ansatz für das Play Framework implementiert und veröffentlicht. Hierbei wird das Formular mit einer Formular-Signatur gegen Parameter Tampering gesichert. Die Felder, welche im Formular vorhanden sind, wenn dieses zum Client geschickt wird, werden gelistet und signiert (SHA256 Hash über Formularfeldliste und den Play-eigenen, app-spezifischen application.secret Config-Wert, den Play auch für die Signierung der Session verwendet). Beim Empfang des Formulars werden die erhaltenen Daten gegen Liste und Hash geprüft, bei Unstimmigkeiten wird ein Fehler generiert.

So setzen Sie SecureForms ein:

1. Den @formKey Template-Helper ins Formular einfügen

2. Das Formular bei Ausgabe signieren:

3. SecureForm anstelle von Form verwenden um Formulareingänge ans Model zu binden:

Details zum Projekt finden Sie hier: https://bitbucket.org/bachi76/play2-secureform (es handelt sich hierbei um das mit Play mitgelieferte Computer Database Beispiel, wobei zu Demozwecken das Hinzufügen von Einträgen ungesichert und das Editieren gesichert wurde).
Happy coding.