Diskussion: Erweiterter Schutz von Passwörtern in Contao
Mit diesem Thread möchte ich gerne zwei Fragen diskutieren:
- Verhinderung der Übermittlung von Passwörtern im Klartext an den Browser.
- Verschlüsseltes Speichern von Passwörtern in der Datenbank
Anstoß hierfür sind u.a. die Tickets #1733 und #1995 und einige Diskussionen hier im Forum.
Zu 1):
Bei den Feldern, die als 'hideInput' = true definert wurden, sind die Eingaben im HTML-Quelltext immer noch sichtbar (darauf weist Leo im Entwicklerhandbuch auch hin!), nur das "über die Schulter schauen" wird hiermit verhindert.
Das kann bei Passwörter-Feldern in seltenen Fällen unangenehme Folgen haben. Loggt sich der Benutzer z.B. bei einem Newsletterverteiler mit eingetragenem SMTP-Server nach dem speichern direkt aus, so könnte im Browser-cache die Seite und somit das Passwort noch enthalten sein. Auch wäre bei einem Hack der Seite (Gott behüte) das Passwort für einen Angreifer direkt auslesbar. Auch ohne Datenbank oder File-Access.
Eine mögliche Lösung wäre, dass beim rendern der Seite das Passwort nicht übermittelt wird. Damit aber auch ein Ändern zu einem leeren Feld möglich bleibt kann wie folgt vorgegangen werden:
Beim Aufbau der Seite wird der vorhandenen Feldinhalte durch eine fixe Zeichenfolge ersetzt (z.B. "***************"). Somit ist dann im value-Attribut des Input-Feldes nur diese Zeichenfolge ersichtlich.
Beim Speichern wird dann geprüft, ob irgendetwas anderes als genau diese Zeichenfolge gesendet wurde. Nur dann wird der neue Wert gespeichert. Wenn nicht, wird der ursprüngliche Wert nicht verändert.
Damit ist für den Anwender erkennbar, dass in dem Feld ein Wert vorhanden ist oder nicht und es kann der Inhalt gelöscht und geändert werden.
Nachteile:
- Die spezielle Zeichefolge (hier "***************") kann nicht mehr als gültiger Wert akzeptiert werden. Daher sollte er ggf. in der config.php definiert werden.
- Der Anwender könnte irrtümlich nur ein Zeichen ändern wollen und erhält dann was ganz anderes. (z.B. beim "ändern" des letzten Zeichens ein "**************A" als neues Passwort. Hier könnte aber vielleicht JS helfen.)
Ein solches Überschreiben könnte auch bei definiertem 'hideInput' = true aber 'doNotShow' = false genutzt werden.
Zu 2):
Da es kaum auszuschließen ist (auch wenn ich es mir wünsche und nichts gegenteiliges weiß), dass es eine Möglichkeit geben könnte, eine SQL-Injection zu realisieren, sollte für alle Passwörter die Möglichkeit existieren diese nur Verschlüsselt in der Datenbank abzugelegen.
Auch wenn der Core eine SQL-Injection sehr effektive verhindert, so ist man nie sicher, auch nicht mit Blick auf alle Extensions, das da alles 100% dicht ist. Wie gesagt, es geht um die Theorie.
Hierzu sind bereits die nötigen Funktionen im Core vorhanden und sollten für alle Passwort-Felder des Core aktivierbar sein.
Hierbei geht es nicht um die Passwörter der Benutzer und User, diese liegen als Hash vor. Auch rede ich explizit nicht von den Passwörtern in der localconfig.php (dort liegt ja auch der Schlüssel für die Verschlüsselung).
Hierzu müssten die Passwortfelder (z.B. tl_newsletter_channel.smtpPass) länger definiert werden. Im konkreten Fall von 32 auf 88 Byte, da zusätzlich zum Passwort noch ein Initialisierungsvektor gespeichert wird und das ganze Base64 codiert ist.
Weiterhin muss vor der Nutzung der Passwörter eine Entschlüsselung stattfinden. Beim Newsletter z.B. nur in der Newsletter::send nach dem Auslesen aus der Datenbank.
Damit es aber keine Probleme mit Servern gibt, die keine mcrypt-Unterstützung bieten, sollte die Verschlüsselung global ein- und ausschaltbar sein, oder aber die class Encryption soll sich transparent verhalten, falls mcrypt fehlt (also nicht ver- und entschlüsseln)
Was meint Ihr dazu?
[hidePass] Passwörter im Backend verstecken
Die Erweiterung hat mittlerweile den Status release candidate 1 erreicht.
Folgende Funktionalitäten sind in Version 0.9.0 enthalten:
- Verstecken eines Passwortes im HTML-Quelltext bei TEXT-Eingabefeldern mit eval-Attribut hideInput
- Berücksichtigung von Verschlüsselter Speicherung (eval-Attribut encrypt)
- JavaScript zum vermeiden von "falschen" Änderungen.
- Konfigurierbarkeit des Platzhalters in den Einstellungen von Contao