it-swarm-eu.dev

Was ist der richtige Weg, um Anti-CSRF-Formular-Token zu implementieren?

Ich bin mir CSRF voll bewusst und habe bereits einige sichere Formulare implementiert, aber ich war noch nie mit den Ergebnissen zufrieden.

Ich habe Token als MD5 aus Benutzername, Formularinfo und Salt erstellt und in einer Sitzung gespeichert. Dies hat ein Problem mit dem Durchsuchen von Registerkarten (kann durch Beibehalten einer Reihe aktiver Hashes behoben werden) und mit dem Timing. Ich möchte, dass meine Hashes nur für z. 10 Minuten, aber wie füge ich eine zeitbezogene Variable in den Hash ein?

Kann mich jemand auf eine gute Ressource verweisen, die beschreibt, wie CSRF-Sicherheit richtig gemacht werden kann?

34
naugtur

Der beste Weg, um den CSRF-Schutz richtig aufzubauen:

Tu es nicht.

In den meisten gängigen Frameworks ist dieser Schutz bereits integriert (ASP.NET, Struts, Ruby, glaube ich), oder es gibt bereits vorhandene Bibliotheken, die bereits überprüft wurden (z. B. CSRFGuard von OWASP ).

Eine weitere Option, abhängig von Ihrem Kontext, besteht darin, die erneute Authentifizierung des Benutzers zu erzwingen, jedoch nur für bestimmte, vertrauliche Vorgänge.


Laut Ihren Kommentaren ist Ihre Lösung nicht schlecht, wenn Sie dies selbst implementieren müssen, aber ich würde es vereinfachen.
Sie können eine kryptozufällige Nonce (lang genug) generieren, diese im Sitzungsspeicher speichern und alle X Minuten ändern (Sie speichern die Ablaufzeit auch in der Sitzung). In jedem Formular fügen Sie die Nonce in ein ausgeblendetes Formularfeld ein und vergleichen diesen Wert, wenn das Formular veröffentlicht wird.
Wenn das Formular-Token übereinstimmt, sind Sie klar. Wenn nicht, können Sie z. das vorherige Token auch, um die Edge-Fälle zu behandeln.

Obwohl ich sagen muss, dass ich zu viele fehlgeschlagene Versuche gesehen habe, dies selbst umzusetzen, um diesen Weg wirklich zu empfehlen. Sie sind immer noch besser dran, ein minimales Paket zu finden, das dies für Sie erledigt.

25
AviD

Es gibt eine gute Erklärung für OWASP: OWASP CSRF Prevention Cheat Sheet

Kurz gesagt, es gibt zwei Möglichkeiten:

  1. Fügen Sie jeder Benutzersitzung ein zufälliges Token hinzu. Nur wenn dieses Token vorhanden und korrekt ist, werden die Änderungen übernommen, andernfalls sollte die Anforderung abgelehnt werden. Es ist wichtig, dass das Token nur mit einer POST - Anforderung gesendet wird, da GET-Anforderungen das Token an verschiedene Stellen (Browserverlauf, Protokolldateien usw.) übertragen können.

    Es ist auch möglich, ein Token pro Anforderung zu generieren, dies führt jedoch zu Usability-Problemen. Zum Beispiel würde die Zurück-Taste nicht mehr richtig funktionieren. Aber natürlich würde die Sicherheit erhöht.

    Stellen Sie außerdem sicher (um die Sicherheit noch weiter zu verbessern), dass das Token nur über TLS gesendet wird, damit sich kein Mann in der Mitte der Probleme befindet.

  2. Die andere Möglichkeit besteht darin, eine Art Herausforderung zu verwenden - eine Antwort (z. B. CAPTCHAs oder einmalige Token).

Die OWASP-Seite listet auch einige Maßnahmen auf, die nicht funktionieren. Diese sind

  • Verwenden von (geheimen) Cookies
  • Keine GET-Anfragen verwenden
  • Mehrstufige Transaktionen
  • URL-Umschreibung
27
Andreas Arnold

Neben der Antwort von @Andreas Arnold gibt es eine Alternative. Ich habe den Encrypted Token Pattern Von OWasp implementiert.

Neben der Verhinderung von CSRF-Angriffen bietet es den zusätzlichen Vorteil, dass die Objektsicherheit implementiert wird.

Dies können nur diejenigen, die berechtigt sind, Objekte zu ändern. Andere haben nicht den richtigen/gültigen Chiffretext oder Schlüssel. Normalerweise verschlüssele ich sessionId, timestamp, userId und/oder recordId.

timestamp verhindert replayAttacks. sessionid isoliert Änderungen nur an dieser Sitzung userId isoliert Änderungen nur an diesem Benutzer. Wenn Sie recordId einschließen, erhalten Sie auf Kosten der zusätzlichen Verarbeitung mehr Sicherheit.

3
Nasir