CORS, oder Cross-Origin Resource Sharing, ist ein Sicherheitsmechanismus, der von Webbrowsern verwendet wird, um zu steuern, welche Webanwendungen Ressourcen von einer anderen DomĂ€ne anfordern dĂŒrfen. Obwohl CORS seit vielen Jahren ein Standard ist, ist es fĂŒr viele Entwickler, insbesondere fĂŒr AnfĂ€nger, schwer zu verstehen. Dieser Artikel zielt darauf ab, CORS umfassend zu erklĂ€ren, die hĂ€ufigsten Fallstricke aufzuzeigen und hilfreiche Tipps zur Implementierung zu geben.

Was ist CORS und warum ist es notwendig? đŸ€”

Um zu verstehen, warum CORS existiert, ist es wichtig, zunĂ€chst das sogenannte Same-Origin-Policy (SOP) Prinzip zu verstehen. Die Same-Origin-Policy ist eine Sicherheitsregel, die verhindert, dass ein Dokument oder Skript, das von einem Ursprung (Domain, Protokoll und Port) stammt, auf Ressourcen eines anderen Ursprungs zugreifen kann. Diese Regel schĂŒtzt vor schĂ€dlichen Angriffen, bei denen bösartige Websites Daten von einem anderen Ursprung stehlen könnten.

Ein einfaches Beispiel:

Du bist auf example.com angemeldet und auf einer Seite dieser Domain eingeloggt. Ohne CORS oder Same-Origin-Policy könnte eine andere bösartige Website, sagen wir badsite.com, versuchen, eine Anfrage an example.com zu senden, um deine vertraulichen Daten abzugreifen.

Cross-Origin Resource Sharing (CORS) - HTTP | MDN
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which browsers make a “preflight” request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.

🔍 Was passiert ohne CORS?

Ohne CORS wĂŒrde der Browser eine solche Anfrage blockieren, um dich zu schĂŒtzen. Dies fĂŒhrt uns zu dem Problem, dass manchmal legitime Anfragen von einer anderen DomĂ€ne ebenfalls blockiert werden, was zu EinschrĂ€nkungen in der Entwicklung moderner Webanwendungen fĂŒhrt.

Hier kommt CORS ins Spiel. CORS ermöglicht es einem Server, Ressourcen fĂŒr Anfragen von bestimmten UrsprĂŒngen freizugeben, wĂ€hrend andere blockiert werden. Dies wird durch spezielle HTTP-Header erreicht, die der Server bei der Antwort auf eine Anfrage sendet.

Season 5 Idk GIF by The Office

Die Funktionsweise von CORS đŸ› ïž

Um zu verstehen, wie CORS funktioniert, mĂŒssen wir die verschiedenen Header, die von einem Server gesendet werden können, genauer betrachten. Die wichtigsten Header, die bei einer CORS-Anfrage ins Spiel kommen, sind:

  1. Access-Control-Allow-Origin: Dieser Header gibt an, welche UrsprĂŒnge Zugriff auf die Ressourcen des Servers haben. Zum Beispiel: Access-Control-Allow-Origin: https://example.com.
  2. Access-Control-Allow-Methods: Dieser Header gibt die HTTP-Methoden an, die der Server fĂŒr Cross-Origin-Anfragen erlaubt (z.B. GET, POST).
  3. Access-Control-Allow-Headers: Dieser Header listet die erlaubten HTTP-Header auf, die von der Anfrage gesendet werden können.

Preflight-Anfragen

Ein wichtiger Bestandteil von CORS ist die sogenannte Preflight-Anfrage. Diese tritt dann auf, wenn eine Anfrage eine Methode verwendet, die nicht in die Kategorie „sicher“ fĂ€llt (z.B. POST, PUT) oder spezielle Header enthĂ€lt. Bevor die eigentliche Anfrage gesendet wird, sendet der Browser eine OPTIONS-Anfrage an den Server, um zu prĂŒfen, ob die eigentliche Anfrage erlaubt ist.

Movie gif. Mark Wahlberg as Elliot in The Happening stares ahead as his eyes glances around in confusion.

Ein Beispiel fĂŒr eine Preflight-Anfrage:

Vorteile von CORS ✅

  1. Sicherheit: Der grĂ¶ĂŸte Vorteil von CORS ist die erhöhte Sicherheit. Es verhindert, dass bösartige Websites auf Ressourcen einer anderen DomĂ€ne zugreifen, was den Datenschutz und die IntegritĂ€t von Daten schĂŒtzt.
  2. Kontrollierter Zugriff: CORS ermöglicht es Servern, genau zu bestimmen, welche Ressourcen von welchen UrsprĂŒngen (Domains) angefordert werden dĂŒrfen. Dies gibt Entwicklern die Kontrolle darĂŒber, wer auf ihre APIs zugreifen kann.
  3. UnterstĂŒtzung fĂŒr moderne Webanwendungen: In einer Zeit, in der Single-Page-Applications und Microservices immer hĂ€ufiger eingesetzt werden, ist CORS unerlĂ€sslich. Es ermöglicht Webanwendungen, nahtlos mit mehreren APIs zu kommunizieren, die auf verschiedenen Domains gehostet werden.

Nachteile von CORS ❌

  1. KomplexitĂ€t: Die Implementierung von CORS kann kompliziert sein, insbesondere fĂŒr Entwickler, die nicht vollstĂ€ndig verstehen, wie es funktioniert. Fehlerhafte Konfigurationen fĂŒhren hĂ€ufig zu Problemen wie blockierten Anfragen und Fehlermeldungen im Browser.
  2. Performance-Einbußen: Jede CORS-Anfrage muss vom Server validiert werden, was die Performance leicht beeintrĂ€chtigen kann, insbesondere wenn viele Anfragen gleichzeitig verarbeitet werden.
  3. Fehlende UnterstĂŒtzung bei Ă€lteren Browsern: Obwohl CORS von modernen Browsern unterstĂŒtzt wird, kann es bei Ă€lteren Versionen zu KompatibilitĂ€tsproblemen kommen.

HĂ€ufige MissverstĂ€ndnisse und Probleme bei CORS 🚧

Viele Entwickler stoßen auf Schwierigkeiten bei der Implementierung von CORS, weil sie nicht vollstĂ€ndig verstehen, wie es funktioniert. Hier sind einige hĂ€ufige MissverstĂ€ndnisse:

  1. CORS ist eine Client-seitige Technologie: Ein weit verbreiteter Irrtum ist, dass CORS von der Client-Seite gesteuert wird. TatsÀchlich wird CORS jedoch auf der Serverseite konfiguriert. Der Server legt fest, ob eine Anfrage von einer anderen DomÀne akzeptiert wird oder nicht.
  2. Einfaches Aktivieren reicht nicht aus: Es reicht nicht aus, einfach CORS auf dem Server zu aktivieren. Entwickler mĂŒssen sicherstellen, dass die richtigen Header gesetzt werden und nur die gewĂŒnschten UrsprĂŒnge zugelassen werden.
  3. Fehlerhafte Preflight-Anfragen: Preflight-Anfragen sind ein Teil von CORS, bei dem der Browser zunĂ€chst ĂŒberprĂŒft, ob der Server die eigentliche Anfrage akzeptieren wird. Wenn diese Preflight-Anfragen fehlschlagen, schlĂ€gt die gesamte Anfrage fehl.

Best Practices fĂŒr die Implementierung von CORS đŸ› ïž

Um Probleme mit CORS zu vermeiden, sollten Entwickler einige bewÀhrte Praktiken beachten:

  1. Spezifische UrsprĂŒnge zulassen: Erlaube nur spezifische Domains, anstatt alle UrsprĂŒnge (*) zu erlauben. Dies erhöht die Sicherheit erheblich.
  2. Preflight-Anfragen verstehen: Preflight-Anfragen werden oft missverstanden. Sie dienen dazu, sicherzustellen, dass der Server die Anfragen zulÀsst. Entwickler sollten sicherstellen, dass ihr Server korrekt auf diese Anfragen reagiert.
  3. Verwendung von Access-Control-Allow-Origin: Dieser Header ist der SchlĂŒssel zur Steuerung von CORS. Er sollte sorgfĂ€ltig gesetzt werden, um die gewĂŒnschten UrsprĂŒnge zuzulassen.

Wichtige CORS-Header đŸ› ïž

HeaderBeschreibung
Access-Control-Allow-OriginGibt an, welche UrsprĂŒnge (Domains) auf die Ressourcen zugreifen dĂŒrfen. Beispiel: https://example.com.
Access-Control-Allow-MethodsListet die HTTP-Methoden auf, die fĂŒr Cross-Origin-Anfragen erlaubt sind (z.B. GET, POST, PUT, DELETE).
Access-Control-Allow-HeadersListet die HTTP-Header auf, die in der Anfrage gesendet werden dĂŒrfen (z.B. Content-Type, Authorization).
Access-Control-Allow-CredentialsGibt an, ob Cookies und andere Anmeldeinformationen als Teil der Anfrage gesendet werden dĂŒrfen.
Access-Control-Expose-HeadersDefiniert, welche Header im Response fĂŒr den JavaScript-Code auf der Client-Seite sichtbar sind.
Access-Control-Max-AgeGibt die Dauer in Sekunden an, fĂŒr die die Ergebnisse der Preflight-Anfrage im Cache des Browsers gespeichert werden.
Access-Control-Request-MethodDieser Header wird in der Preflight-Anfrage vom Browser gesendet, um die beabsichtigte HTTP-Methode (z.B. POST) anzugeben.
Access-Control-Request-HeadersWird ebenfalls in der Preflight-Anfrage vom Browser gesendet, um die HTTP-Header anzugeben, die verwendet werden sollen.

Detaillierte ErklĂ€rung der CORS-Header 📝

Access-Control-Allow-Origin

Dieser Header ist der wichtigste in der CORS-Implementierung. Er gibt an, welche UrsprĂŒnge (Domains) Zugriff auf die Ressourcen des Servers haben dĂŒrfen. Wenn du beispielsweise möchtest, dass nur Anfragen von https://example.com erlaubt sind, setzt du diesen Header wie folgt: Access-Control-Allow-Origin: https://example.com. Ein hĂ€ufiges MissverstĂ€ndnis ist die Verwendung von *, was bedeutet, dass alle UrsprĂŒnge erlaubt sind. Obwohl dies einfach ist, kann es ein Sicherheitsrisiko darstellen.

Access-Control-Allow-Methods

Dieser Header listet die HTTP-Methoden auf, die der Server fĂŒr Cross-Origin-Anfragen zulĂ€sst. Typische Methoden sind GET, POST, PUT und DELETE. Zum Beispiel könnte der Header so aussehen: Access-Control-Allow-Methods: GET, POST. Es ist wichtig, nur die Methoden zuzulassen, die tatsĂ€chlich benötigt werden, um das Sicherheitsrisiko zu minimieren.

Access-Control-Allow-Headers

Wenn die Anfrage zusĂ€tzliche Header wie Content-Type oder Authorization benötigt, muss der Server diese explizit erlauben. Dieser Header definiert, welche Header in der Anfrage vorhanden sein dĂŒrfen. Ein Beispiel wĂ€re: Access-Control-Allow-Headers: Content-Type, Authorization. Dadurch kann der Server spezifische Header zulassen, die fĂŒr die Anfrage notwendig sind.

Access-Control-Allow-Credentials

Dieser Header gibt an, ob der Browser Anmeldeinformationen (wie Cookies oder HTTP-Auth-Daten) mit der Anfrage senden darf. Wenn der Server beispielsweise einen Cookie setzen möchte, muss dieser Header auf true gesetzt werden: Access-Control-Allow-Credentials: true. Es ist wichtig zu beachten, dass dieser Header in Kombination mit Access-Control-Allow-Origin verwendet wird, wobei der Wert von Access-Control-Allow-Origin nicht * sein darf.

Access-Control-Expose-Headers

StandardmĂ€ĂŸig sind nicht alle HTTP-Header im Response fĂŒr JavaScript im Browser sichtbar. Dieser Header definiert, welche Header im Response fĂŒr den Client sichtbar sind. Wenn du möchtest, dass der Client auf einen speziellen Header wie X-Custom-Header zugreifen kann, wĂŒrdest du diesen Header so setzen: Access-Control-Expose-Headers: X-Custom-Header.

Access-Control-Max-Age

Dieser Header gibt an, wie lange (in Sekunden) die Ergebnisse einer Preflight-Anfrage im Cache des Browsers gespeichert werden dĂŒrfen. Beispielsweise könnte der Header so aussehen: Access-Control-Max-Age: 86400, was bedeutet, dass die Antwort 24 Stunden lang im Cache bleiben darf. Dies kann die Performance verbessern, da Preflight-Anfragen fĂŒr einen bestimmten Zeitraum nicht erneut gesendet werden mĂŒssen.

Access-Control-Request-Method

Dieser Header wird vom Browser bei einer Preflight-Anfrage gesendet und gibt an, welche HTTP-Methode die eigentliche Anfrage verwenden wird, z.B. POST oder GET. Der Server ĂŒberprĂŒft dann, ob diese Methode zulĂ€ssig ist.

Access-Control-Request-Headers

Dieser Header wird ebenfalls bei einer Preflight-Anfrage vom Browser gesendet. Er gibt die HTTP-Header an, die in der eigentlichen Anfrage verwendet werden sollen, z.B. Content-Type. Der Server prĂŒft dann, ob diese Header zulĂ€ssig sind.

Durch das VerstĂ€ndnis dieser Header und ihrer Funktionen können Entwickler sicherstellen, dass ihre Webanwendungen korrekt und sicher mit verschiedenen UrsprĂŒngen kommunizieren können.

Wie CORS richtig implementiert wird đŸ› ïž

Die korrekte Implementierung von CORS erfordert ein gutes VerstÀndnis der Header und der Funktionsweise von HTTP-Anfragen. Hier sind einige bewÀhrte Praktiken:

  1. Spezifische UrsprĂŒnge zulassen: Verwende eine Whitelist fĂŒr vertrauenswĂŒrdige UrsprĂŒnge anstelle von Wildcards. Dies reduziert die AngriffsflĂ€che erheblich.
  2. Exakte Header angeben: Sei genau bei der Angabe der erlaubten Methoden und Header. Es ist besser, restriktiver zu sein, um potenzielle SicherheitslĂŒcken zu vermeiden.
  3. Preflight-Anfragen korrekt behandeln: Stelle sicher, dass dein Server korrekt auf OPTIONS-Anfragen reagiert und die richtigen Header zurĂŒckgibt.
You Rock GIF by iFLY Indoor Skydiving

Beispiele aus der Praxis đŸ–„ïž

Um zu veranschaulichen, wie CORS in der Praxis funktioniert, hier ein einfaches Beispiel:

Einfache GET-Anfrage

Stell dir vor, du baust eine Webseite auf https://mywebsite.com, die Daten von einer API auf https://api.example.com abruft. Der Server auf https://api.example.com muss CORS so konfigurieren, dass er Anfragen von https://mywebsite.com erlaubt.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://mywebsite.com
Content-Type: application/json

{
  "message": "Erfolgreich abgerufen"
}

In diesem Fall erhÀlt der Browser die Daten, weil der Server den Ursprung https://mywebsite.com erlaubt hat.

POST-Anfrage mit Preflight

Angenommen, du möchtest Daten an https://api.example.com senden. Da dies eine nicht-sichere Methode (POST) ist, wird der Browser zuerst eine Preflight-Anfrage senden.

Preflight-Request:

OPTIONS /data
Host: api.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
Origin: https://mywebsite.com

Antwort des Servers:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://mywebsite.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type

Fazit 📜

CORS ist eine essenzielle Technologie fĂŒr moderne Webentwicklung, die sowohl Sicherheitsvorteile als auch Herausforderungen mit sich bringt. FĂŒr AnfĂ€nger kann es schwierig sein, CORS richtig zu implementieren, aber mit dem richtigen Wissen und einigen Best Practices kann man hĂ€ufige Fallstricke vermeiden. Es ist wichtig, dass du dich mit den Grundlagen von CORS vertraut machst und weißt, wie du es richtig implementierst, um sowohl die Sicherheit als auch die FunktionalitĂ€t deiner Webanwendungen zu gewĂ€hrleisten.

Damit ist es möglich, dass nur ein Frontend (von einer bestimmten Domain) auf bestimmte Teile der API zugreifen kann und nichts anderes. Gerade im Hinblick auf die Entwicklung von APIs ist es umso wichtiger, CORS wirklich zu verstehen. Wenn deine eigene API entwickeln möchtest, habe ich hier einen kleinen Leitfaden fĂŒr dich:

Eigene API mit NodeJS und Express
Du willst dir eine eigene API fĂŒr deine Dienste bauen? Wir machen es zusammen 👇

und eine ErklÀrung wie REST-APIs funktionieren:

REST-APIs verstehen und nutzen
APIs: AllgegenwĂ€rtig und jeder nutzt sie , wenn auch in direkt. Aber wofĂŒr sind sie da und wie funktionieren sie? Wir klĂ€ren auf 💡

oder GraphQL funktioniert:

GraphQL: Zukunft der APIs 🌐
GraphQL vs. REST: Entdecke die Vorteile und Nachteile der modernen Abfragesprache fĂŒr APIs! 🌐

Diskutiere gerne in den Kommentaren unten, ob du schon einmal auf CORS-Probleme gestoßen bist und wie du diese gelöst hast!