Umgang mit CORS in Webanwendungen

0
279
Shutterstock/Gorodenkoff

CORS ist ein Browsermechanismus, mit dem Server die Herkunft von Drittanbietern angeben können, die Ressourcen von ihnen anfordern können. Es ist ein Sicherheitsschutz, der verhindert, dass bösartige Websites Daten anderer Herkunft stehlen.

CORS steht für Cross-Origin Resource Sharing. Wenn CORS zum Laden einer Ressource verwendet wird, sendet der Browser normalerweise eine “Preflight” HTTP OPTIONS-Anfrage. Der Server muss antworten und die Ursprünge angeben, mit denen er interagiert. Es können auch zusätzliche Einschränkungen definiert werden, z. B. die HTTP-Header, die gesendet werden können.

Der Browser überprüft den aktuellen Ursprung und die ausgehende Anfrage anhand der Serverspezifikationen. Die Anforderung darf fortgesetzt werden, wenn alle Prüfungen erfolgreich waren. Andernfalls wird die ursprüngliche Anfrage storniert. In diesem Fall wird in der Konsole eine Warnung angezeigt.

Wenn CORS verwendet wird

Browser erzwingen CORS für Ajax- und Fetch-Anfragen. Der Mechanismus wird auch für Webfonts, WebGL-Texturen und Canvas-Bildzeichnungen mit drawImage() verwendet. Jede berechtigte Anfrage an einen Drittanbieter-Ursprung erfordert einen CORS-Austausch.

CORS wird nicht durchgesetzt, wenn die Anfrage als “einfach” angesehen wird. Eine einfache Anfrage muss GET, HEAD oder POST mit einem Inhaltstyp von text/plain, application/x-www-form-urlencoded oder multipart/form-data sein. Die einzigen zulässigen einfachen Request-Header sind Accept, Accept-Language, Content-Language und Content-Type.

Wenn die Anfrage nicht alle oben genannten Kriterien erfüllt, wird ein CORS-Austausch von modernen Browsern gestartet. Es ist wichtig zu erkennen, dass CORS eine browserbasierte Technologie ist – Sie werden niemals auf CORS stoßen, wenn Sie manuell Anfragen stellen, z. B. mit curl in Ihrem Terminal.

CORS-Börsen senden nicht immer eine OPTIONS-Preflight-Anfrage. Ein Preflight wird verwendet, wenn die Anfrage “Nebeneffekte” auf dem Server. Dies ist im Allgemeinen bei anderen Anforderungsmethoden als GET der Fall.

Stellen Sie sich eine POST-Anfrage an /api/users/create vor. Der Server würde immer einen neuen Benutzer erstellen, aber der Browser kann den Zugriff auf die Antwort verweigern, wenn die Anfrage CORS unterliegt. Indem er zuerst eine OPTIONS-Anfrage sendet, hat der Server die Möglichkeit, die eigentliche Anfrage explizit abzulehnen. Dadurch wird sichergestellt, dass das Benutzerkonto nicht tatsächlich erstellt wird.

Behandlung von CORS-Clientseite

Obwohl es sich bei CORS um eine Browsertechnologie handelt, können Sie diese nicht direkt mit clientseitigem Code beeinflussen. Dadurch wird verhindert, dass bösartige Skripts den CORS-Schutz umgehen, um Daten von Drittanbieter-Domains zu laden.

CORS ist normalerweise transparent, sodass Sie nicht bemerken, dass es in Betrieb ist. Wenn ein CORS-Austausch fehlschlägt, wird in Ihrem JavaScript-Code ein allgemeiner Netzwerkfehler angezeigt. Es ist nicht möglich, genaue Angaben darüber zu erhalten, was schief gelaufen ist, da dies ein Sicherheitsrisiko darstellen würde. Die vollständigen Details werden in der Konsole protokolliert.

Die einzige Möglichkeit, einen CORS-Fehler zu beheben, besteht darin, sicherzustellen, dass Ihr Server die richtigen Antwortheader sendet. Sehen wir uns nun an, wie das geht.

Umgang mit CORS-Serverseite

Sie sollten zunächst sicherstellen, dass Ihr Server OPTIONS-Anfragen korrekt verarbeitet. Möglicherweise müssen Sie eine neue Route in Ihrem Web-Framework erstellen. Im Allgemeinen müssen Sie OPTIONS-Anfragen an jeden Endpunkt akzeptieren, der möglicherweise eine ursprungsübergreifende Anfrage von einem Browser erhält. Die Antwort muss keinen Textkörper enthalten, muss jedoch bestimmte Header enthalten, die dem Browser mitteilen, wie er fortfahren soll.

Beginnen Sie mit dem Hinzufügen des Headers Access-Control-Allow-Origin. Dies gibt den Drittanbieter-Ursprung an, der mit Ihrem Endpunkt kommunizieren darf. Es kann nur ein Ursprung angegeben werden; Sie können mehrere Ursprünge handhaben, indem Sie den Wert des Headers dynamisch auf den Ursprung setzen, von dem die Anfrage gesendet wurde. Sie können die aktuelle Herkunft aus dem Origin-Request-Header abrufen.

Access-Control-Allow-Origin akzeptiert * als speziellen Platzhalterwert. Dies ermöglicht CORS-Anfragen von allen Ursprüngen. Seien Sie vorsichtig, wenn Sie dieses – Spezifisch mit den zulässigen Ursprüngen zu sein gibt Ihnen mehr Kontrolle und verhindert, dass bösartige Skripte Daten von Ihrem Server anfordern.

Access-Control-Allow-Origin muss in der Antwort Ihres Servers auf die echte Anfrage sowie in der OPTIONS-Antwort enthalten sein. Sobald dieser einzelne Header eingerichtet ist, ist ein einfacher Austausch mit einem Browser-Client eines Drittanbieters zulässig.

Angeben von Cross-Origin-Headern

CORS-Anfragen unterstützen normalerweise nur die “einfachen” oben aufgeführten Anforderungsheader. Wenn Sie einen anderen Header wie Authorization oder einen benutzerdefinierten Header verwenden müssen, muss Ihr Server dies in der Preflight-Antwort explizit zulassen.

Legen Sie den Header Access-Control-Allow-Headers fest. Sein Wert sollte eine durch Kommas getrennte Liste von Header-Namen sein, die mit der echten Anfrage akzeptiert werden.

Access-Control-Allow-Headers: Authorization, X-Custom-Header

Der Browser erlaubt nun, dass eine Anfrage mit den Headern Authorization oder X-Custom-Header fortgesetzt wird.

Wenn der Browser sendet einer CORS-Preflight-Anfrage sendet es den Header Access-Control-Request-Headers. Diese enthält die Liste der Header, die mit der eigentlichen Anfrage gesendet werden. Ihr Servercode kann diese Informationen verwenden, wenn er bestimmt, wie auf die Preflight-Anfrage reagiert werden soll.

Beschränkung auf bestimmte Anforderungsmethoden

Ähnlich wie bei der Angabe von Anforderungsheadern können Serverendpunkte definieren, welche HTTP-Methoden ursprungsübergreifend zugelassen werden sollen. Setzen Sie den Access-Control-Allow-Methods-Header als kommagetrennte Liste von Methodennamen.

Access-Control-Allow-Methods: GET, POST, DELETE

Der Browser sendet die Access-Control-Request- Methodenheader mit CORS-Preflights. Dies teilt Ihrem Server die HTTP-Methode mit, die verwendet wird, um die endgültige Anfrage zu stellen.

Cookies und Anmeldeinformationen

CORS-Anfragen senden normalerweise keine Cookies, da sie sensible Anmeldeinformationen enthalten können, die den Absender identifizieren. Wenn Sie Cookies in eine ursprungsübergreifende Anfrage einschließen müssen, müssen Sie dies explizit in Ihrem clientseitigen Code aktivieren:

fetch(“https://localhost/demo”, { mode: “cors”, Credentials: “einschließen” });

Darüber hinaus muss der Server den Access-Control-Allow-Credentials: true-Antwortheader setzen, um seine Zustimmung zu signalisieren, dass Cookies mit Anmeldeinformationen ausgetauscht werden können.

Wenn Sie Access-Control-Allow-Credentials verwenden, kann nicht den Platzhalter (*) mit Access-Control-Allow-Origin verwenden. Der Server muss stattdessen einen expliziten Ursprung angeben, um die Privatsphäre des Benutzers zu schützen. Wenn der Platzhalter gesendet wird, schlägt der Browser die Anfrage mit einem CORS-Fehler fehl.

Preflight-Caching

CORS OPTIONS-Preflights fügen jeder von Ihnen gestellten Anfrage einen Overhead hinzu. Obwohl die Verzögerung bei einer guten Netzwerkverbindung kaum wahrnehmbar sein sollte, ist es dennoch verschwenderisch, wenn Sie denselben Endpunkt mehrmals kurz hintereinander aufrufen.

Sie können dem Browser sagen, dass er zwischenspeichern soll Preflight-Antworten durch Festlegen des Headers Access-Control-Max-Age. Der Wert sollte die Zeit in Sekunden sein, für die der Browser die Antwort zwischenspeichern darf. Nachfolgende Anfragen an denselben Endpunkt innerhalb des angegebenen Zeitraums senden kein CORS-Preflight.

Schlussfolgerung

CORS kann beim ersten Auftreten verwirrend erscheinen. Es ist eine Browsertechnologie, die durch Serverantworten gesteuert wird. CORS ist unvermeidbar und dennoch unkontrollierbar, es sei denn, Sie haben Zugriff auf den serverseitigen Code, mit dem Sie interagieren.

Die eigentliche Implementierung von CORS ist recht einfach. Stellen Sie sicher, dass Ihre API oder Ihr CDN die richtigen Antwortheader sendet, insbesondere Access-Control-Allow-Origin. Sie haben dann eine sichere ursprungsübergreifende Kommunikation, die Ihnen hilft, sich vor schlechten Akteuren zu schützen.