OAuth2 csrf_detected mit Discord 'Connect'-Funktionalität

Hallo! Ich brauche dringend Hilfe bei der Lösung dieses Fehlers:


Schritte zur Reproduktion:
Wenn ein Benutzer in den Einstellungen auf die Schaltfläche “Verbinden” von Discord klickt,


wird der Benutzer korrekt zur Autorisierungsseite von Discord weitergeleitet.

Nachdem der Benutzer jedoch auf die Schaltfläche “Autorisieren” geklickt hat, wird er weitergeleitet und erhält diese Meldung in unserem Forum:
image
und der Fehler am Anfang dieses Themas wird in den Admin-Protokollen angezeigt.


Ich glaube, ich habe alles gelesen und versucht, um dies zu beheben, aber es passiert weiterhin. Ich habe sichergestellt, dass die Discord Client ID und das Secret der Website-Einstellungen korrekt sind.
Ich habe auch sichergestellt, dass die URI die richtige Syntax hatte (basierend auf einigen verwandten Themen, die ich gesehen habe):

Irgendwelche Vorschläge? Ich bin bereit, alles zu versuchen, auch wenn Sie sich nicht sicher sind, ob es funktioniert :laughing:

Irgendwelche Ideen? Habe immer noch Probleme damit :confused:

Ich glaube (?), ich habe es auf ein Nginx- und/oder Caching-Problem eingegrenzt? Sollten in discourse.conf spezifische Authentifizierungs- oder CSRF-spezifische Dinge definiert sein, die wir möglicherweise übersehen?

@merefield, @david, @sam - Entschuldigung für die Pings, aber ich sehe Ihre Namen in vielen der älteren CSRF-bezogenen Diskussionen in der Vergangenheit. Haben Sie Empfehlungen dafür? Da die Discord-Authentifizierung ein integrierter Bestandteil von Discourse ist, bin ich ratlos, was dies verursachen könnte.

Ich schätze jede Hilfe im Voraus, danke :smiling_face:

Wir müssen gegen eines davon verstoßen?

Ich kann immer noch kein Muster finden. Manchmal funktioniert es und verbindet mich korrekt, aber manchmal werde ich mit der CSRF-Seite konfrontiert.
Im Moment bin ich am misstrauischsten gegenüber der letzten Bedingungsprüfung in verified_request?.
Gibt es einfache Möglichkeiten zu überprüfen, ob (valid_request_origin? && any_authenticity_token_valid?) true zurückgibt?

Ich entschuldige mich für das Fehlen von debugfähigen Informationen, aber ich glaube, ich habe das Problem (schmerzlich) gefunden (zumindest was ich glaube). Ich bin mir immer noch nicht sicher, wie die Lösung aussieht, also lesen Sie bitte weiter :kissing_heart:


Die folgenden Bilder zeigen eine direkte Instanz, in der ich mein Konto erfolgreich verknüpfen konnte, es aktualisierte/erneut versuchte und erfolglos auf der CSRF-erkannten Seite landete. Ich befand mich in einem Inkognito-Fenster und habe zwischen der erfolgreichen Verbindung und dem CSRF-Fehler buchstäblich nichts getan/geändert. Hier ist, was ich gefunden habe:

Dieses erste Bild zeigt, dass die _forum_session-Cookie-Übereinstimmung in beiden Anfrageheadern 1 und 2 zu einer erfolgreichen Verbindung führte.

Nachdem ich die Seite neu geladen und es erneut versucht hatte (und die Verbindung fehlschlug), können Sie sehen, dass meine Suche auf der linken Seite nur 1 Vorkommen des _forum_session-Cookies in einem Anfrageheader zeigt, als es zu einem Fehler kam.

tl;dr: Ich bin ziemlich sicher, dass das Problem vom forum_session-Cookie im discord?reconnect-Anfrageheader und dann im folgenden callback?-Anfrageheader herrührt, die nicht übereinstimmen. Was würde dazu führen, dass sie unterschiedlich sind?

Ok, ich glaube, wir kommen der Sache näher.

In diesem Bild unten sehen Sie, dass eine Update-POST-Anfrage direkt nach der discord?reconnect-POST-Anfrage erfolgt.


Und siehe da, es wird der _forum_session-Cookie gesetzt, was dazu führt, dass er nicht übereinstimmt, wie ich oben beschrieben habe.

Wenn ich eine erfolgreiche Verbindungsinstanz überprüfe (unten), sehen Sie, dass das Update nur vor der discord?reconnect-POST-Anfrage erfolgt.

Dies führt dazu, dass der _forum_session-Cookie übereinstimmt und das Konto erfolgreich ohne das CSRF-Problem verbunden wird.

Wie kann ich verhindern, dass dieses Update nach Beginn des Verbindungsvorgangs durch den Benutzer erfolgt?

@FerrariFlunker Entschuldigung für die langsame Antwort, aber ich hatte noch keine Gelegenheit, mir das anzusehen. Es wäre großartig, wenn das Kernteam das tun könnte.

Wenn es ein Trost ist, kann ich es reproduzieren, ich glaube, ich bekomme denselben Fehler:

(discord) Authentifizierungsfehler! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF erkannt

Kein Problem @merefield, ich schätze die Antwort!

Tritt dieser Fehler in Ihrer eigenen Umgebung auf? Ich denke, dieser Fehler muss auf jeden Fall vom Kernteam untersucht werden. Ich bin seit über 2 Wochen dabei, ihn zu debuggen und habe immer noch keine Antwort gefunden :confused:

1 „Gefällt mir“

Gut recherchiert! Diese Art von Race Condition könnte sicherlich die Probleme verursachen, die Sie sehen.

Davon abgesehen haben wir keine anderen Berichte über dieses Problem erhalten, daher scheint es etwas zu sein, das spezifisch für Ihre Website/Konfiguration ist. Welche Plugins haben Sie auf der Website installiert? Können Sie den “update”-Aufruf öffnen und sehen, welche Nutzlast gesendet wird?

3 „Gefällt mir“

Nachdem ich mir die Update-Aufrufe angesehen habe, denke ich, Sie haben Recht. Hier sind einige Screenshots von bestätigten „update“-Anfragen, die zu CSRF-Fehlern geführt haben.

Ich sehe ein Muster, das mit CDN zu tun hat :face_with_monocle: Was könnte damit falsch konfiguriert sein? Lassen Sie mich wissen, ob Sie immer noch eine Liste unserer Plugins benötigen. Ich dachte nur, ich würde diese Antwort mit +1 Bild :smile: retten.

1 „Gefällt mir“

Ich habe ein aufregendes Update! Vor ein paar Tagen habe ich mir die ‘update’-Payload genauer angesehen und konnte Folgendes erfolgreich zuordnen:

zu einem unserer Plugins! :partying_face: :expressionless: :smile:
Nachdem ich das Plugin deaktiviert, weitere Tests durchgeführt und die zugehörige Funktion erfolgreich für die Community gestartet hatte… glaube ich, dass ich mit Zuversicht sagen kann, dass wir den Schuldigen gefunden haben.

Dieses Plugin hat sich also als Übeltäter herausgestellt: GitHub - discourse/discourse-chat: Chat inside Discourse

Rückblickend ergibt es Sinn, warum dies der Schuldige sein könnte – das Plugin ist immer noch als experimentell gekennzeichnet und nicht für Produktionsseiten gedacht. :sweat:

Da ich über 3 Wochen mit der Diagnose dieses Problems beschäftigt war und wieder mit den anderen Projekten unserer Community vorankommen muss :face_with_spiral_eyes:, werde ich leider nicht in der Lage sein, bei der Behebung des discourse-chat-Plugins zu helfen.

Wenn jemand eine Korrektur für das Plugin vornimmt, werden wir (höchstwahrscheinlich :smile:) in Erwägung ziehen, das Plugin auf unserer Seite wieder zu aktivieren, aber im Moment brauchen wir stabile, zugeordnete Account-Connect-Funktionalität.

Nochmals vielen Dank an alle, die bei der Diagnose geholfen haben! :+1:

2 „Gefällt mir“

Vielen Dank für die super detaillierte Untersuchung, @FerrariFlunker!

Ich habe gerade einen PR für eine Korrektur im Discourse-Kern erstellt:

Der Grund, warum es nach dem Entfernen des Chat-Plugins behoben war, ist, dass Chat diese ‘PresenceChannel’-API intensiv nutzt, und daher ist es weitaus wahrscheinlicher, dass das Problem auftritt. Ich glaube nicht, dass Änderungen am Chat erforderlich sein werden.

4 „Gefällt mir“

Sollte dies dasselbe Problem mit Google-Logins beheben? Meine Benutzer auf einer meiner Instanzen, auf denen wir das Chat-Plugin getestet haben, liebten es, aber es hat die Google-Logins mit demselben Fehler wie die Discord-Logins unterbrochen.

5 „Gefällt mir“

Ja, dieser Fix wird für alle verschiedenen Anmeldetypen angewendet :+1:

3 „Gefällt mir“