1063 Stimmen

Das Rails-Authentizitäts-Token verstehen

Ich bin in einige Probleme in Bezug auf die Authentizität Token in Rails laufen.

Ich würde das Echtheitsmerkmal wirklich gerne verstehen.

Haben Sie eine vollständige Informationsquelle zu diesem Thema oder würden Sie sich die Zeit nehmen, dies hier im Detail zu erklären?

1537voto

Faisal Punkte 19028

Was geschieht

Wenn der Benutzer ein Formular aufruft, um eine Ressource zu erstellen, zu aktualisieren oder zu zerstören, erstellt die Rails-App eine zufällige authenticity_token speichert dieses Token in der Sitzung und platziert es in einem verborgenen Feld des Formulars. Wenn der Benutzer das Formular absendet, sucht Rails nach dem authenticity_token und vergleicht sie mit der in der Sitzung gespeicherten, und wenn sie übereinstimmen, kann die Anfrage fortgesetzt werden.

Warum das so ist

Da das Authentizitätstoken in der Sitzung gespeichert wird, kann der Client seinen Wert nicht kennen. Dadurch wird verhindert, dass Personen Formulare an eine Rails-Anwendung übermitteln, ohne das Formular in der Anwendung selbst zu sehen. Stellen Sie sich vor, Sie nutzen den Dienst A, Sie haben sich bei dem Dienst angemeldet und alles ist in Ordnung. Nun stellen Sie sich vor, dass Sie den Dienst B nutzen und ein Bild sehen, das Ihnen gefällt, und auf das Bild klicken, um es in einer größeren Version zu sehen. Wenn nun ein böser Code bei Dienst B vorhanden wäre, könnte er eine Anfrage an Dienst A (bei dem Sie angemeldet sind) senden und darum bitten, Ihr Konto zu löschen, indem er eine Anfrage an http://serviceA.com/close_account . Dies ist das, was man als CSRF (Cross Site Request Forgery) .

Wenn Dienst A Authentizitäts-Token verwendet, ist dieser Angriffsvektor nicht mehr anwendbar, da die Anfrage von Dienst B nicht das korrekte Authentizitäts-Token enthalten würde und daher nicht fortgesetzt werden kann.

API-Dokumente beschreibt Details zum Meta-Tag:

Der CSRF-Schutz wird mit der Option protect_from_forgery Methode, die das Token prüft und die Sitzung zurücksetzt, wenn es nicht mit dem übereinstimmt, was erwartet wurde. Ein Aufruf dieser Methode wird für neue Rails Anwendungen standardmäßig erzeugt. Der Token-Parameter heißt authenticity_token standardmäßig. Der Name und der Wert dieses Tokens müssen zu jedem Layout hinzugefügt werden, das Formulare durch Einfügen von csrf_meta_tags im HTML-Kopf.

Notas

Beachten Sie, dass Rails nur nicht idempotente Methoden (POST, PUT/PATCH und DELETE) prüft. GET-Anfragen werden nicht auf Authentizitäts-Token geprüft. Warum? Weil die HTTP-Spezifikation besagt, dass GET-Anfragen idempotent sind und no Ressourcen auf dem Server erstellen, ändern oder zerstören, und die Anfrage sollte idempotent sein (wenn Sie denselben Befehl mehrmals ausführen, sollten Sie jedes Mal dasselbe Ergebnis erhalten).

Auch die tatsächliche Implementierung ist etwas komplizierter als anfangs definiert, um eine bessere Sicherheit zu gewährleisten. Rails gibt nicht bei jedem Formular das gleiche gespeicherte Token aus. Es wird auch nicht jedes Mal ein anderes Token erzeugt und gespeichert. Es generiert und speichert einen kryptographischen Hash in einer Session und gibt jedes Mal, wenn eine Seite gerendert wird, neue kryptographische Token aus, die mit dem gespeicherten abgeglichen werden können. Siehe request_forgery_protection.rb .

Lektionen

Verwenden Sie authenticity_token um Ihre nicht idempotenten Methoden (POST, PUT/PATCH und DELETE) zu schützen. Stellen Sie außerdem sicher, dass Sie keine GET-Anfragen zulassen, die möglicherweise Ressourcen auf dem Server verändern könnten.


EDITAR: Siehe der Kommentar von @erturne dass GET-Anfragen idempotent sind. Er erklärt es besser, als ich es hier getan habe.

151voto

Topher Fangio Punkte 19756

Das Authentizitäts-Token ist so konzipiert, dass Sie wissen, dass Ihr Formular von Ihrer Website aus übermittelt wird. Es wird von dem Rechner, auf dem es ausgeführt wird, mit einer eindeutigen Kennung generiert, die nur Ihr Rechner kennen kann, und hilft so, Cross-Site Request Forgery-Angriffe zu verhindern.

Wenn Sie einfach Schwierigkeiten damit haben, dass Rails Ihrem AJAX-Skript den Zugriff verweigert, können Sie

<%= form_authenticity_token %>

um das richtige Token zu erzeugen, wenn Sie Ihr Formular erstellen.

Mehr darüber erfahren Sie in der Dokumentation .

99voto

Rose Perrone Punkte 58235

Was ist CSRF?

Das Authenticity Token ist eine Gegenmaßnahme zur Cross-Site Request Forgery (CSRF). Was ist CSRF, fragen Sie?

Auf diese Weise kann ein Angreifer möglicherweise Sitzungen entführen, ohne die Sitzungs-Tokens zu kennen.

Szenario :

  • Besuchen Sie die Website Ihrer Bank und loggen Sie sich ein.
  • Besuchen Sie dann die Website des Angreifers (z. B. gesponserte Werbung von einer nicht vertrauenswürdigen Organisation).
  • Die Seite des Angreifers enthält ein Formular mit denselben Feldern wie das Formular "Geld überweisen" der Bank.
  • Der Angreifer kennt Ihre Kontodaten und hat vorausgefüllte Formularfelder, um Geld von Ihrem Konto auf das Konto des Angreifers zu überweisen.
  • Die Seite des Angreifers enthält Javascript, das ein Formular an Ihre Bank sendet.
  • Wenn das Formular abgeschickt wird, speichert der Browser Ihre Cookies für die Bank-Website, einschließlich des Sitzungs-Tokens.
  • Die Bank überweist Geld auf das Konto des Angreifers.
  • Das Formular kann sich in einem unsichtbaren Iframe befinden, so dass Sie nicht wissen, dass der Angriff stattgefunden hat.
  • Dies wird als Cross-Site Request Forgery (CSRF) bezeichnet.

CSRF-Lösung :

  • Server kann Formulare markieren, die vom Server selbst stammen
  • Jedes Formular muss ein zusätzliches Authentifizierungs-Token als verstecktes Feld enthalten.
  • Der Token muss unvorhersehbar sein (der Angreifer kann ihn nicht erraten).
  • Der Server bietet gültige Token in Formularen auf seinen Seiten an.
  • Server prüft Token beim Absenden des Formulars, lehnt Formulare ohne korrektes Token ab.
  • Beispiel Token: Sitzungskennung, verschlüsselt mit dem geheimen Schlüssel des Servers.
  • Rails generiert solche Token automatisch: siehe das Eingabefeld authenticity_token in jedem Formular.

71voto

Adam Zerner Punkte 14785

Das Authentizitätstoken wird verwendet, um Cross-Site Request Forgery-Angriffe (CSRF) zu verhindern. Um das Authentizitäts-Token zu verstehen, müssen Sie zunächst CSRF-Angriffe verstehen.

CSRF

Angenommen, Sie sind der Autor von bank.com . Sie haben ein Formular auf Ihrer Website, das dazu dient, mit einer GET-Anfrage Geld auf ein anderes Konto zu überweisen:

enter image description here

Ein Hacker könnte einfach eine HTTP-Anfrage an den Server senden mit den Worten GET /transfer?amount=$1000000&account-to=999999 richtig?

enter image description here

Falsch. Der Hackerangriff wird nicht funktionieren. Der Server wird grundsätzlich denken?

Hm? Wer ist dieser Typ, der versucht, einen Transfer zu initiieren. Der Kontoinhaber ist es nicht, das ist sicher.

Woher weiß der Server das? Weil es keine session_id Cookie zur Authentifizierung des Antragstellers.

Wenn Sie sich mit Ihrem Benutzernamen und Passwort anmelden, setzt der Server eine session_id Cookie in Ihrem Browser. Auf diese Weise müssen Sie sich nicht bei jeder Anfrage mit Ihrem Benutzernamen und Passwort authentifizieren. Wenn Ihr Browser die session_id Cookie, weiß der Server:

Oh, das ist John Doe. Er hat sich vor 2,5 Minuten erfolgreich angemeldet. Er ist einsatzbereit.

Ein Hacker könnte denken:

Hm. Eine normale HTTP-Anfrage wird nicht funktionieren, aber wenn ich das in die Finger kriegen könnte session_id Keks, dann wäre ich glücklich.

Der Browser des Benutzers hat eine Reihe von Cookies für die bank.com Bereich. Jedes Mal, wenn der Benutzer eine Anfrage an die bank.com Domain werden alle Cookies mitgeschickt. Einschließlich der session_id Keks.

Wenn also ein Hacker in der Lage wäre Sie um die GET-Anfrage zu stellen, die Geld auf sein Konto überweist, wäre er erfolgreich. Wie könnte er Sie dazu verleiten? Mit Cross Site Request Forgery.

Eigentlich ist es ganz einfach. Der Hacker könnte Sie einfach dazu bringen, seine Website zu besuchen. Auf seiner Website könnte er das folgende Bild-Tag verwenden:

<img src="http://bank.com/transfer?amount=$1000000&account-to=999999">

Wenn der Browser des Benutzers auf dieses Bild-Tag stößt, wird er eine GET-Anfrage an diese URL stellen. Und da die Anfrage von seinem Browser kommt, sendet er alle Cookies mit, die mit bank.com . Wenn sich der Benutzer kürzlich bei bank.com ... die session_id Cookie gesetzt, und der Server wird denken, dass der Benutzer $1.000.000 auf das Konto 999999 überweisen wollte!

enter image description here

Besuchen Sie einfach keine gefährlichen Seiten, dann wird alles gut.

Das ist nicht genug. Was ist, wenn jemand das Bild auf Facebook postet und es auf Ihrer Pinnwand erscheint? Was ist, wenn es mit einem XSS-Angriff in eine Website eingefügt wird, die Sie besuchen?

Es ist nicht so schlimm. Nur GET-Anfragen sind anfällig.

Das stimmt nicht. Ein Formular, das eine POST-Anfrage sendet, kann dynamisch erstellt werden. Hier ist das Beispiel aus dem Rails-Leitfaden zur Sicherheit :

<a href="http://www.harmless.com/" onclick="
  var f = document.createElement('form');
  f.style.display = 'none';
  this.parentNode.appendChild(f);
  f.method = 'POST';
  f.action = 'http://www.example.com/account/destroy';
  f.submit();
  return false;">To the harmless survey</a>

Echtheitstoken

Wenn Ihr ApplicationController hat dies:

protect_from_forgery with: :exception

Dies:

<%= form_tag do %>
  Form contents
<% end %>

wird hierin zusammengefasst:

<form accept-charset="UTF-8" action="/" method="post">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
  Form contents
</form>

Insbesondere wird das Folgende erzeugt:

<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />

Um sich vor CSRF-Angriffen zu schützen, betrachtet Rails die Anfrage als nicht sicher, wenn es das Authentizitäts-Token nicht sieht, das zusammen mit der Anfrage gesendet wird.

Woher soll ein Angreifer wissen, was dieses Token ist? Jedes Mal, wenn das Formular generiert wird, wird ein anderer Wert nach dem Zufallsprinzip erzeugt:

enter image description here

Ein Cross-Site-Scripting (XSS)-Angriff - das ist die Lösung. Aber das ist eine andere Schwachstelle für einen anderen Tag.

49voto

Minimales Beispiel für einen Angriff, der verhindert werden könnte: CSRF

Auf meiner Website evil.com Ich bitte Sie, das folgende Formular auszufüllen:

<form action="http://bank.com/transfer" method="post">
  <p><input type="hidden" name="to"      value="ciro"></p>
  <p><input type="hidden" name="ammount" value="100"></p>
  <p><button type="submit">CLICK TO GET PRIZE!!!</button></p>
</form>

Wenn Sie über Sitzungscookies bei Ihrer Bank angemeldet sind, werden die Cookies gesendet und die Überweisung wird durchgeführt, ohne dass Sie es merken.

An dieser Stelle kommt das CSRF-Token ins Spiel:

  • mit der GET-Antwort, die das Formular zurückgegeben hat, sendet Rails einen sehr langen zufälligen versteckten Parameter
  • Wenn der Browser die POST-Anfrage stellt, sendet er den Parameter mit, und der Server akzeptiert ihn nur, wenn er mit

So würde das Formular in einem echten Browser aussehen:

<form action="http://bank.com/transfer" method="post">
  <p><input type="hidden" name="authenticity_token" value="j/DcoJ2VZvr7vdf8CHKsvjdlDbmiizaOb5B8DMALg6s=" ></p>
  <p><input type="hidden" name="to"                 value="ciro"></p>
  <p><input type="hidden" name="ammount"            value="100"></p>
  <p><button type="submit">Send 100$ to Ciro.</button></p>
</form>

Somit würde mein Angriff fehlschlagen, da er nicht die authenticity_token Parameter, und ich hätte ihn auf keinen Fall erraten können, da es sich um eine große Zufallszahl handelt.

Diese Präventionstechnik wird als Synchronisations-Token-Muster .

Politik der gleichen Herkunft

Was aber, wenn der Angreifer zwei Anfragen mit JavaScript stellt, eine, um das Token zu lesen, und die zweite, um die Übertragung durchzuführen?

Das Synchronisierungs-Token-Muster allein reicht nicht aus, um dies zu verhindern!

Hier kommt die Same Origin Policy zur Hilfe, wie ich unter erläutert habe: https://security.stackexchange.com/questions/8264/why-is-the-same-origin-policy-so-important/72569#72569

Wie Rails die Token sendet

Abgedeckt bei: Geländer: Wie funktioniert csrf_meta_tag?

Im Grunde genommen:

  • HTML-Hilfsmittel wie form_tag ein verstecktes Feld in das Formular einfügen, wenn es sich nicht um ein GET-Formular handelt

  • AJAX wird automatisch behandelt von jquery-ujs der das Token aus der Datei meta Elemente, die Ihrer Kopfzeile durch csrf_meta_tags (die in der Standardvorlage enthalten ist) und fügt sie zu jeder Anfrage hinzu.

    uJS versucht auch, das Token in Formularen in veralteten gecachten Fragmenten zu aktualisieren.

Andere Präventionsansätze

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X