Wann ist es sicher, CORS zu aktivieren?

78

Ich entwickle eine JSON / REST-Web-API, für die ich speziell möchte, dass Websites von Drittanbietern meinen Dienst über AJAX aufrufen können. Daher sendet mein Dienst den berühmten CORS-Header:

Access-Control-Allow-Origin: *

Dadurch können Websites von Drittanbietern meinen Dienst über AJAX aufrufen. Alles in Ordnung soweit.

Ein Unterabschnitt meiner Web-API ist jedoch nicht öffentlich und erfordert eine Authentifizierung (ziemlich normales Zeug mit OAuth und einem access_token-Cookie). Ist es sicher, CORS auch auf diesem Teil meiner Website zu aktivieren?

Einerseits wäre es cool, wenn Websites von Drittanbietern Ajax-Clients haben könnten, die auch mit diesem Teil meines Dienstes interagieren. Der Grund dafür, dass es in erster Linie dieselbe Ursprungspolitik gibt, ist jedoch, dass dies riskant sein kann. Sie möchten nicht, dass eine Website, die Sie anschließend besuchen, auf Ihre privaten Inhalte zugreifen kann.

Das Szenario, vor dem ich Angst habe, ist, dass sich ein Benutzer in meiner Web-API anmeldet, entweder auf der Website oder über eine Website, der er vertraut, und vergisst, sich abzumelden. Ermöglicht dies jeder anderen Website, die er später besucht, über die vorhandene Sitzung auf seine privaten Inhalte zuzugreifen?

Also meine Fragen:

  • Ist es jemals sicher, CORS für nicht öffentliche Inhalte zu aktivieren?
  • Wenn ein CORS-fähiger Server ein session_token über ein Cookie setzt, wird dieses Cookie unter der Domäne des CORS-Servers oder des Hauptwebseiten-Servers gespeichert?
Jeroen
quelle
2
Beachten Sie, dass Sie die CORS-Header nur an die Ressourcen senden können, auf die andere von anderen Ursprüngen aus zugreifen sollen. Sie können den CORS-Zugriff auch auf die Ursprünge beschränken, von denen Sie eine Nutzung erwarten.
Dan D.
1
Ich möchte, dass alle Ressourcen von jedem Ursprung aus zugänglich sind, wenn die Sicherheit dies zulässt. Es ist weiterhin Sache des Benutzers, gültige Anmeldeinformationen anzugeben. Ich möchte nur sicherstellen, dass ich nicht die Tür für Cross-Site-Scripting-Angriffe von bösartigen Websites öffne.
Jeroen

Antworten:

45

Als Antwort auf Ihre zweite Frage (Wenn ein CORS-fähiger Server ein session_token über ein Cookie setzt ...?) Wird das Cookie unter der Domäne des CORS-Servers gespeichert. Der JS-Code der Hauptwebseite kann auch über nicht auf das Cookie zugreifen document.cookie. Das Cookie wird nur an den Server gesendet, wenn die .withCredentialsEigenschaft festgelegt ist, und selbst dann wird es nur akzeptiert, wenn der Server den Access-Control-Allow-CredentialsHeader festlegt .

Ihre erste Frage ist etwas offener. Es ist ziemlich sicher, aber es gibt Möglichkeiten, Dinge zu umgehen. Ein Angreifer könnte beispielsweise eine DNS-Vergiftungstechnik verwenden, um eine Preflight-Anforderung auf den tatsächlichen Server zu übertragen, die tatsächliche CORS-Anforderung jedoch an den nicht autorisierten Server senden. Hier sind einige weitere Ressourcen zur CORS-Sicherheit:

Schließlich geht es Ihnen darum, jeder Website Zugriff auf Ihre CORS-Daten zu gewähren . Um sich davor zu schützen, sollten Sie den Access-Control-Allow-Origin: *Header nicht verwenden . Stattdessen sollten Sie den Origin-Wert des Benutzers zurückgeben. Zum Beispiel:

Access-Control-Allow-Origin: http://www.example.com

Dieser Header erlaubt nur http://www.example.comden Zugriff auf die Antwortdaten.

Monsur
quelle
4
Können Sie klarstellen, wie das Echo des 'Origin'-Headers die Sicherheit erhöht? Ich würde denken, dass jede bösartige Website / jedes bösartige Skript auch diesen Header leicht setzen könnte? Oder meinst du damit, eine Art Whitelist zu führen?
Jeroen
5
Ja, eine Whitelist akzeptabler Herkunft zu führen, ist eine Lösung. Eine andere Möglichkeit besteht darin, eine Benutzersitzungs-ID an einen bestimmten Ursprung zu binden. Auf diese Weise schlägt ein anderer Ursprung fehl, wenn die Anforderung auf irgendeine Weise mit den Anmeldeinformationen des Benutzers abgespielt wird.
Monsur
Ich denke, Sie wollen damit sagen, dass ein Angreifer den Preflight abfangen würde, nicht die eigentliche Anfrage. Beachten Sie auch, dass GETs nicht vorgeflogen sind.
Csauve
3
GETs können vorab geflogen werden, wenn sie nicht einfache Anforderungsheader enthalten.
Monsur
1
@Jeroen Es ist ein Missverständnis, dass jede böswillige Website / jedes böswillige Skript den Origin-Header setzen kann, da der Header ein "verbotener" Header ist, gemäß der CORS-Spezifikation: fetch.spec.whatwg.org/#forbidden-header-name
Peter Thomassen
25

Die Absicht von CORS ist es, Ursprungsübergreifende Anforderungen für XHR-Anforderungen zuzulassen und dem Server die Berechtigung zu geben, anzugeben, welcher Ursprung Zugriff auf welche Ressource hat. Insbesondere hat CORS das Origin- Headerfeld eingeführt, mit dem der Server reguläre und mögliche XHR-Anforderungen unterscheiden kann. Dieses Header-Feld kann vom Benutzer nicht festgelegt oder geändert werden, wird jedoch vom Browser für XHR-Anforderungen festgelegt.

Wenn Sie also eine API haben, die nur von XHR verwendet werden soll, können (und sollten) Sie verlangen, dass die Anforderung mit CORS übereinstimmt. Insbesondere, wenn die Anforderungen auch den Status auf Ihrem Server ändern können, da Sie sonst für CSRF anfällig wären.

Beachten Sie, dass CSRF-Angriffe unabhängig von CORS mit anderen Methoden zum Fälschen von GET- und POST-Anforderungen möglich sind. CORS ermöglicht nur dann den Zugriff auf die Antwort des Servers auf XHR-Anforderungen mit JavaScript, wenn der Server dies zulässt.

Gumbo
quelle