Es gibt viele Arten des Vertrauens. Ich möchte heute über Kundenvertrauen reden und was wir tun können um es uns zu verdienen.
Kommen wir also endlich zum Thema: Sicherheit. Meist unterpriorisiert und dank Magento ist das nicht ganz so schlimm, denn wie sagt Basti immer: "Im Vergleich zu anderer Software ist Magento ziemlich sicher". Nichts desto trotz gibt es neben den üblichen Empfehlungen, die man bei der Magento-Programmierung und dem Hosting beherzigen sollte:
- Admin-Pfad ändern
- Ordentliche Passwörter
- KEIN eigenes SQL, GARKEINS!
- Höchste Vorsicht mit Benutzereingaben und der Ausgabe selbiger (XSS)
- ...
andere Probleme, mit denen wir uns bisher nicht so beschäftigt haben, nämlich alles um das Thema Sessions.
Warum man Sessions schützen sollte
Es geht um Vertrauen. Es geht um Sicherheit. Der Kunde im Shop soll sich sicher fühlen. Dazu trägt unter anderem bei, dass er uns seine Daten bedenkenlos anvertrauen kann. Niemand kauft bei uns ein, wenn er glaubt, dass mit seiner Kreditkarte zwanzig Sekunden später irgendwo anders eingekauft wird. Oder er damit rechnen muss, dass wir seine Einkäufe inkl. seiner Adresse und E-Mailadresse weiterverkaufen.
Genau das gleiche gilt für die Session unseres Kunden. Eine Session muss geschützt werden, und jetzt sind wir im Thema. Aus Kundensicht kann ein Angreifer eine Menge Unsinn mit der Session machen. Wenn die Session übernommen wurde, kann man Adressdaten ändern und dafür sorgen, dass die Pakete woanders hin geschickt werden (z.B. zu uns). In einer Standard-Magento-Installation werden zusätzlich alle Enkäufe im Kundenbereich aufgelistet. Außerdem finden wir die Wunschliste, die Tags und die Reviews eines Kunden. Man kann sich also einen guten Überblick über ihn verschaffen. Dank der Abfrage des aktuellen Passworts, kann man es nicht einfach ändern, aber der Umweg über Email-Adresse ändern, Passwort vergessen, Passwort ändern, Mailadresse zurück ändern geht.
Aus Shopbetreibersicht, gibt es aber auch einige Gründe, neben dem Vertrauensaspekt, die Session des Kunden zu schützen. Eingeloggte Kunden können ihre Download-Produkte nochmal herunterladen. Bekommt also jemand die Session, bezahlt er nicht für die MP3, das Ebook, etc. Besonders übel wird es bei Kundenkreditprogrammen und Belohnungs- und Punktesammelsystemen und kaufen auf Rechnung. Dann muss nur die neue Adresse eingegeben werden und bezahlt wird mit den bisher gesammelten Punkten oder dem Guthaben welches man noch im Shop hat. Der Kunde wurde geprellt und ist sauer und wir haben gerade Ware verschenkt.
Danke an dieser Stelle an Vinai und Pavel für die Recherchehilfe.
Wie schützen wir eine Session
Transport Layer Security
TLS ist das Stichwort. Den meisten dürfte es unter dem alten Namen SSL bekannt sein oder der Implementierung auf HTTP: HTTPS. Aus meiner Sicht als Programmierer, gibt es keinen Grund mehr, auf HTTPS zu verzichten. Ein Shop sollte nur über HTTPS erreichbar sein.
Secure Cookies
Nachdem der erste Schritt getan ist und alle URLs nur via HTTPS erreichbar sind, bleibt das Problem, dass Kunden für gewöhnlich www.mein-shop.de in ihren Browser eingeben, das führt dazu, dass eine 302 Weiterleitung von http://www.mein-shop.de auf https://www.mein-shop.de gemacht wird. Entweder der Kunde hat bereits eine Session-ID, dann wird diese unverschlüsselt über das Netzwerk übertragen (z.B. das offene WLAN vom Starbucks) oder aber, der Server vergibt eine neue via Set-Cookie, die dann auch unverschlüssel vom Server an den Client geht. In jedem Fall: Wenn jemand mit hört, hat er gerade unsere Session-ID erfahren. Die mit der wir uns dann gleich einloggen!
Das lässt sich verhinden, indem bei den Cookies das "Secure"-Attribut gesetzt wird. Das sorgt dafür, dass das Cookie dann nur über HTTPS übertragen wird. Mehr dazu im RFC 6265.
Es sei noch erwähnt, dass die Gefahr, dass eine Session-ID gestohlen wird minimiert wird, wenn zusätzlich das "httpOnly" Attribut auf dem Cookie gesetzt wird. Dadurch kann JavaScript weder den Inhalt des Cookies lesen noch schreiben. Dies macht Magento glücklicherweise bereits für uns!
Session Fixation
Eine eingeloggte Session-ID zu klauen ist aber nicht der einzige Weg an eine authentifizierte Session zu gelangen. Ein weiterer Weg ist ein sog. "Session-Fixation" Angriff. Bei diesem Angriff stiehlt man dem Benutzer nicht die authentifizierte Session, sondern schiebt ihm eine Session-ID unter. Der Unterschied ist, dass der Angreifer in diesem Szenario die Session-ID während des kompletten Ablaufs kennt und nur darauf warten muss, bis der Benutzer sich einloggt.
Leider ist es bei PHP sehr einfach eine Session unterzuschieben, nämlich so: http://www.mein-shop.de/?SID=12345. Wichtig hierbei zu verstehen ist, dass eine Session-ID, die via GET gesetzt wird, jeden Cookie überschreibt, mindestens in der Standardkonfiguration.
Magento ändert seit der Version 1.5 die Session-ID während des Logins. Habt ihr eine ältere Version, aktualisiert. Ich habe - bevor ich das erfahren habe - ein Modul implementiert, welches das auch tut, evtl. hilft euch das: Ikonoshirt_SecureSession
HTTP Strict Transport Security (HSTS)
HSTS sorgt kurz gesagt dafür, dass ein Shop nur per HTTPS erreichbar ist. Im Detail verschickt der Server einen HTTP Header der für eine bestimmte Zeit den Browser anweist die Domain (evtl. inkl Subdomains) nur über HTTPS anzusprechen. Empfohlen werden hier 6-12 Monate. Das ist ein Ansatz gegen "HTTPS stripping attacks". Wenn ihr mehr wissen wollt, folgt den Links. Und auch hier habe ich ein Modul geschrieben. Das Modul implementiert HSTS inkl. ein paar Prüfungen, z.B. ob die unsecure und die secure_base_url https sind: Ikonoshirt_StrictTransportSecurity.