CORS: Cross-Origin Resource Sharing konfigurieren
Hallo User,
heute hatte ich das Vergnügen mich mit CORS zu beschäftigen. Ein netter Hacker hat uns darauf hingewiesen, das wir dazu nichts konfiguriert haben.
Was ist CORS?
Das Cross-Origin Resource Sharing (CORS) ermöglicht fremden Webbrowsern oder anderen Webclients bestimmte Zugriffe auf Daten des eigenen Webservers. Normalerweise sind diese durch die Same-Origin-Policy (SOP - Gleiche-Herkunft-Richtlinie) untersagt. In der Regel geht es dabei um Web-APIs und dem Austausch von Daten.
Da wir unsere Daten mit niemanden austauschen, war mir bisher nicht klar, warum wir eine CORS Regel dazu brauchen. Wie immer kann man alles mögliche manipulieren und Hacker empfehlen, dass man die CORS so einstellen sollte, dass man selbst seine Inhalte laden darf. Wer sich auf Hackerseiten tummelt findet auch schnell das Thema: "Vulnerability : CROSS ORIGIN RESOURCE SHARING". Die Empfehlungen der Hackergemeinde lautet daher wie folgt:
Allgemeine Informationen zu CORS findet ihr unter den folgenden Links:
Wie testet man auf CORS?
Man kann im Browser die gewünschte Seite aufrufen und z.B. mit Hilfe des Menüs "Element untersuchen" die Developer Tools des Browsers starten (z.B. Firefox auf dem Mac: option+cmd+i). Unter Netzwerk Analyse findet man nach dem Klick auf die Seite den entsprechenden Header. Hier ein Beispiel:
Das kann je nach Browser und System natürlich unterschiedlich sein, aber letztendlich habe allen Browser eine ähnliche Ansicht.
Leichter geht es zum Beispiel per curl in der Konsole:
Tipp: Solltet ihr euch auf einem Entwicklungssystem mit ungültigen SSL-Zertifikat befinden, müsst ihr ein "-k" als curl Option hinzufügen (z.B. curl -k -I -X OPTIONS -H ....). Das unterdrückt das ungültige Zertifikat.
Bei beiden Methoden sollte im Header golgendes stehen:
Ist "Access-Control-Allow-Origin" vorhanden, wir die CORS geregelt. Dort kann natürlich auch ein "*" drin stehen. Damit erlaubt man alle Zugriffe von anderen Servern. Bei öffentlichen APIs werdet ihr das in der Regel so vorfinden.
Wie stelle ich CORS ein?
Das kann man auf unterschiedliche Weise machen: Über den Proxy, im Webserver oder per Script. Hat man z.B. einen HAProxy und will CORS allgemein einstellen, muss man lediglich ein paar Zeilen Code zur Config hinzufügen:
Nachteil - es wird alles geblockt
Das hat allerdings einen sehr großen Nachteil. Seiten, die von Werbung leben, haben dann das Problem, dass auch alle Werbesystem bzw. ihre Javascripts ab sofort geblockt werden. Voraussetzung dafür ist natürlich der Eintrag der eigenen Domäne und nicht dem "*". Das ist für uns also nicht die Lösung (sicher, aber unpraktisch).
Per HEADER einstellen
Man sollte es daher feiner einstellen. Bei uns wäre das z.B. der Login, die Seiten für Einstellungen, Nachrichten etc. Das ist bei uns der Mitglieder Bereich. Da dort sowieso keine Werbung angezeigt wird, können wir hier ansetzen.
Unter PHP kann man sehr einfach den Seiten-HEADER setzen, somit brauchen wir hier nicht in die Konfiguration des Proxys oder des Webservers eingreifen. Ein einfaches:
auf den jeweiligen Seiten genügt, um die Sicherheit durch CORS einzustellen. Danach sollte man es wieder im Browser oder per curl prüfen. Wenn man alles richtig gemacht hat, erscheint ein und alles ist wieder gut. Das funktioniert natürlich mit allen Sprachen, die einen HEADER setzen können.
Ich hoffe ich konnte damit einigen Web-Entwicklern helfen. Das Thema ist komplex, lässt sich dann aber recht einfach umsetzen.
Wer eine API absichern will und mehrere definierte Domains erlauben möchte findet hier einen guten Ansatz:
Gruß
Frank
heute hatte ich das Vergnügen mich mit CORS zu beschäftigen. Ein netter Hacker hat uns darauf hingewiesen, das wir dazu nichts konfiguriert haben.
Was ist CORS?
Das Cross-Origin Resource Sharing (CORS) ermöglicht fremden Webbrowsern oder anderen Webclients bestimmte Zugriffe auf Daten des eigenen Webservers. Normalerweise sind diese durch die Same-Origin-Policy (SOP - Gleiche-Herkunft-Richtlinie) untersagt. In der Regel geht es dabei um Web-APIs und dem Austausch von Daten.
Da wir unsere Daten mit niemanden austauschen, war mir bisher nicht klar, warum wir eine CORS Regel dazu brauchen. Wie immer kann man alles mögliche manipulieren und Hacker empfehlen, dass man die CORS so einstellen sollte, dass man selbst seine Inhalte laden darf. Wer sich auf Hackerseiten tummelt findet auch schnell das Thema: "Vulnerability : CROSS ORIGIN RESOURCE SHARING". Die Empfehlungen der Hackergemeinde lautet daher wie folgt:
Rather than using a wildcard or programmatically verifying supplied origins, use a whitelist of trusted domains.
Allgemeine Informationen zu CORS findet ihr unter den folgenden Links:
- Cross-Origin Resource Sharing (CORS) Erklärung auf Mozilla.org
- Cross-Origin Resource Sharing auf Wikipedia
- Was ist CORS und welche Sicherheitsauswirkungen hat es auf Web-Applikationen?
Wie testet man auf CORS?
Man kann im Browser die gewünschte Seite aufrufen und z.B. mit Hilfe des Menüs "Element untersuchen" die Developer Tools des Browsers starten (z.B. Firefox auf dem Mac: option+cmd+i). Unter Netzwerk Analyse findet man nach dem Klick auf die Seite den entsprechenden Header. Hier ein Beispiel:
Das kann je nach Browser und System natürlich unterschiedlich sein, aber letztendlich habe allen Browser eine ähnliche Ansicht.
Leichter geht es zum Beispiel per curl in der Konsole:
curl -I -X OPTIONS -H "Origin: https://DOMAIN.TLD" -H 'Access-Control-Request-Method: GET' https://DOMAIN.TLD/index.php 2>&1 | grep 'Access-Control-Allow-Origin'
Tipp: Solltet ihr euch auf einem Entwicklungssystem mit ungültigen SSL-Zertifikat befinden, müsst ihr ein "-k" als curl Option hinzufügen (z.B. curl -k -I -X OPTIONS -H ....). Das unterdrückt das ungültige Zertifikat.
Bei beiden Methoden sollte im Header golgendes stehen:
Access-Control-Allow-Origin: https://DOMAIN.TLD
Ist "Access-Control-Allow-Origin" vorhanden, wir die CORS geregelt. Dort kann natürlich auch ein "*" drin stehen. Damit erlaubt man alle Zugriffe von anderen Servern. Bei öffentlichen APIs werdet ihr das in der Regel so vorfinden.
Wie stelle ich CORS ein?
Das kann man auf unterschiedliche Weise machen: Über den Proxy, im Webserver oder per Script. Hat man z.B. einen HAProxy und will CORS allgemein einstellen, muss man lediglich ein paar Zeilen Code zur Config hinzufügen:
frontend https-in
# Add CORS headers when Origin header is present
capture request header origin len 128
http-response add-header Access-Control-Allow-Origin %[capture.req.hdr(0)] if { capture.req.hdr(0) -m found }
rspadd Access-Control-Allow-Methods:\ GET,\ HEAD,\ OPTIONS,\ POST,\ PUT if { capture.req.hdr(0) -m found }
rspadd Access-Control-Allow-Credentials:\ true if { capture.req.hdr(0) -m found }
rspadd Access-Control-Allow-Headers:\ Origin,\ Accept,\ X-Requested-With,\ Content-Type,\ Access-Control-Request-Method,\ Access-Control-Request-Headers,\ Authorization if { capture.req.hdr(0) -m found }
Nachteil - es wird alles geblockt
Das hat allerdings einen sehr großen Nachteil. Seiten, die von Werbung leben, haben dann das Problem, dass auch alle Werbesystem bzw. ihre Javascripts ab sofort geblockt werden. Voraussetzung dafür ist natürlich der Eintrag der eigenen Domäne und nicht dem "*". Das ist für uns also nicht die Lösung (sicher, aber unpraktisch).
Per HEADER einstellen
Man sollte es daher feiner einstellen. Bei uns wäre das z.B. der Login, die Seiten für Einstellungen, Nachrichten etc. Das ist bei uns der Mitglieder Bereich. Da dort sowieso keine Werbung angezeigt wird, können wir hier ansetzen.
Unter PHP kann man sehr einfach den Seiten-HEADER setzen, somit brauchen wir hier nicht in die Konfiguration des Proxys oder des Webservers eingreifen. Ein einfaches:
header("Access-Control-Allow-Orgin: https://administrator.de");
header("Access-Control-Allow-Methods: GET,POST");
auf den jeweiligen Seiten genügt, um die Sicherheit durch CORS einzustellen. Danach sollte man es wieder im Browser oder per curl prüfen. Wenn man alles richtig gemacht hat, erscheint ein
Access-Control-Allow-Origin: https://administrator.de
Ich hoffe ich konnte damit einigen Web-Entwicklern helfen. Das Thema ist komplex, lässt sich dann aber recht einfach umsetzen.
Wer eine API absichern will und mehrere definierte Domains erlauben möchte findet hier einen guten Ansatz:
Gruß
Frank
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 603642
Url: https://administrator.de/contentid/603642
Ausgedruckt am: 21.11.2024 um 21:11 Uhr
1 Kommentar
Moin Frank,
dazu gehört auch CSP (,wenn ich das richtig sehe, hat administrator.de gar keine).
Das habe ich mal für unsere Websites eingeführt, was bei viel externen Content nicht ganz trivial ist und immer mal wieder durchs "audit" muss. Aber Du kannst damit die Sicherheit erhöhen und Dein Ranking erhöhen, nicht dass Du's brauchst
Grundsätzliches hier:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
Und eine Testmöglichkeit hier:
https://observatory.mozilla.org/
Gruss
dazu gehört auch CSP (,wenn ich das richtig sehe, hat administrator.de gar keine).
Das habe ich mal für unsere Websites eingeführt, was bei viel externen Content nicht ganz trivial ist und immer mal wieder durchs "audit" muss. Aber Du kannst damit die Sicherheit erhöhen und Dein Ranking erhöhen, nicht dass Du's brauchst
Grundsätzliches hier:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
Und eine Testmöglichkeit hier:
https://observatory.mozilla.org/
Gruss