frank
Goto Top

CORS: Cross-Origin Resource Sharing konfigurieren

article-picture
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:
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:


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:

bildschirmfoto 2020-09-10 um 18.20.04

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. face-smile

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
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

Content-Key: 603642

Url: https://administrator.de/contentid/603642

Printed on: April 25, 2024 at 15:04 o'clock

Member: sabines
sabines Sep 11, 2020 at 08:40:17 (UTC)
Goto Top
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 brauchstface-wink

Grundsätzliches hier:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

Und eine Testmöglichkeit hier:
https://observatory.mozilla.org/

Gruss