Ein umfassender Leitfaden zu Cross-Origin Resource Sharing (CORS), der Konfiguration, Sicherheitsauswirkungen und Best Practices für Entwickler behandelt.
Cross-Origin Resource Sharing (CORS): Konfiguration und Best Practices für die Sicherheit
In der Welt der Webentwicklung ist Sicherheit von größter Bedeutung. Ein kritischer Aspekt der Websicherheit ist die Verwaltung, wie Webseiten von einem Ursprung auf Ressourcen von einem anderen Ursprung zugreifen können. Hier kommt Cross-Origin Resource Sharing (CORS) ins Spiel. CORS ist eine Sicherheitsfunktion des Browsers, die Webseiten daran hindert, Anfragen an eine andere Domain zu stellen als die, von der die Webseite bereitgestellt wurde. Dieser Mechanismus soll verhindern, dass bösartige Websites auf sensible Daten zugreifen. Dieser Artikel bietet einen umfassenden Leitfaden zu CORS, der dessen Konfiguration, Sicherheitsauswirkungen und Best Practices behandelt.
Die Same-Origin-Policy verstehen
CORS baut auf dem Fundament der Same-Origin-Policy auf, einem fundamentalen Sicherheitsmechanismus, der von Webbrowsern implementiert wird. Die Same-Origin-Policy beschränkt Webseiten darin, Anfragen an eine andere Domain als die zu stellen, von der die Webseite bereitgestellt wurde. Zwei URLs gelten als vom selben Ursprung, wenn sie dasselbe Protokoll (z. B. HTTP oder HTTPS), denselben Host (z. B. example.com) und denselben Port (z. B. 80 oder 443) haben. Zum Beispiel:
http://example.comundhttp://example.com/pathhaben denselben Ursprung.http://example.comundhttps://example.comhaben unterschiedliche Ursprünge (unterschiedliche Protokolle).http://example.comundhttp://www.example.comhaben unterschiedliche Ursprünge (unterschiedliche Hosts).http://example.com:80undhttp://example.com:8080haben unterschiedliche Ursprünge (unterschiedliche Ports).
Die Same-Origin-Policy soll Cross-Site-Scripting-Angriffe (XSS) verhindern, bei denen eine bösartige Website Skripte in eine vertrauenswürdige Website einschleust, um Benutzerdaten zu stehlen oder unbefugte Aktionen durchzuführen. Ohne die Same-Origin-Policy könnte eine bösartige Website potenziell auf Ihre Bankkontoinformationen zugreifen, wenn Sie in einem anderen Tab in Ihrem Online-Banking-Portal angemeldet wären.
Was ist Cross-Origin Resource Sharing (CORS)?
Obwohl die Same-Origin-Policy für die Sicherheit entscheidend ist, kann sie in legitimen Szenarien, in denen Websites auf Ressourcen von verschiedenen Ursprüngen zugreifen müssen, auch einschränkend sein. Zum Beispiel muss eine Webanwendung, die auf example.com gehostet wird, möglicherweise Daten von einer API abrufen, die auf api.example.net gehostet wird. CORS bietet einen Mechanismus, um die Same-Origin-Policy kontrolliert zu umgehen, sodass Webseiten ursprungsübergreifende Anfragen stellen können, wenn dies vom Server explizit autorisiert wurde.
CORS funktioniert durch das Hinzufügen von HTTP-Headern zur Antwort des Servers, die angeben, welche Ursprünge auf die Ressource zugreifen dürfen. Der Browser überprüft dann diese Header und blockiert die Anfrage, wenn der Ursprung der anfragenden Webseite nicht zulässig ist.
Wie CORS funktioniert: Die HTTP-Header
CORS stützt sich auf spezifische HTTP-Header, um ursprungsübergreifende Anfragen zu ermöglichen. Hier sind die wichtigsten beteiligten Header:
1. Origin (Anfrage-Header)
Der Origin-Header wird vom Browser bei ursprungsübergreifenden Anfragen gesendet. Er gibt den Ursprung (Protokoll, Host und Port) der Webseite an, die die Anfrage stellt. Zum Beispiel:
Origin: http://example.com
2. Access-Control-Allow-Origin (Antwort-Header)
Der Access-Control-Allow-Origin-Header ist der wichtigste Header bei CORS. Er gibt an, welche Ursprünge auf die Ressource zugreifen dürfen. Er kann einen der folgenden Werte haben:
- Ein spezifischer Ursprung: Zum Beispiel erlaubt
Access-Control-Allow-Origin: http://example.comnur Anfragen vonhttp://example.com. *(Wildcard):Access-Control-Allow-Origin: *erlaubt Anfragen von jedem Ursprung. Dies sollte mit Vorsicht verwendet werden, da es die Same-Origin-Policy für diese Ressource effektiv deaktiviert.
Beispiel:
Access-Control-Allow-Origin: https://www.example.com
3. Access-Control-Allow-Methods (Antwort-Header)
Der Access-Control-Allow-Methods-Header gibt die HTTP-Methoden (z. B. GET, POST, PUT, DELETE) an, die bei der ursprungsübergreifenden Anfrage erlaubt sind. Dies ist für Preflight-Anfragen erforderlich (siehe unten).
Beispiel:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
4. Access-Control-Allow-Headers (Antwort-Header)
Der Access-Control-Allow-Headers-Header gibt die HTTP-Header an, die bei der ursprungsübergreifenden Anfrage erlaubt sind. Dies ist ebenfalls für Preflight-Anfragen erforderlich.
Beispiel:
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With
5. Access-Control-Allow-Credentials (Antwort-Header)
Der Access-Control-Allow-Credentials-Header gibt an, ob der Browser Anmeldeinformationen (z. B. Cookies, Autorisierungs-Header) in die ursprungsübergreifende Anfrage einbeziehen soll. Er kann einen von zwei Werten haben: true oder false. Wenn true gesetzt ist, kann der Access-Control-Allow-Origin-Header nicht auf * gesetzt werden. Es muss ein spezifischer Ursprung sein.
Beispiel:
Access-Control-Allow-Credentials: true
6. Access-Control-Max-Age (Antwort-Header)
Der Access-Control-Max-Age-Header gibt die Anzahl der Sekunden an, für die der Browser die Ergebnisse der Preflight-Anfrage zwischenspeichern kann. Dies kann die Leistung verbessern, indem die Anzahl der Preflight-Anfragen reduziert wird.
Beispiel:
Access-Control-Max-Age: 3600
Einfache Anfragen vs. Preflight-Anfragen
CORS unterscheidet zwischen zwei Arten von ursprungsübergreifenden Anfragen: einfachen Anfragen und Preflight-Anfragen.
Einfache Anfragen
Eine einfache Anfrage ist eine Anfrage, die die folgenden Kriterien erfüllt:
- Die Methode ist
GET,HEADoderPOST. - Wenn die Methode
POSTist, ist derContent-Type-Header einer der folgenden:application/x-www-form-urlencoded,multipart/form-dataodertext/plain. - Die Anfrage setzt keine benutzerdefinierten Header (außer denen, die automatisch vom Browser gesetzt werden).
Bei einfachen Anfragen sendet der Browser die Anfrage direkt an den Server. Der Server antwortet dann mit den entsprechenden CORS-Headern. Wenn der Ursprung erlaubt ist, verarbeitet der Browser die Antwort. Andernfalls blockiert der Browser die Antwort und löst einen Fehler aus.
Preflight-Anfragen
Eine Preflight-Anfrage wird vom Browser gesendet, bevor die eigentliche ursprungsübergreifende Anfrage gestellt wird, wenn die Anfrage nicht die Kriterien für eine einfache Anfrage erfüllt. Dies geschieht typischerweise, wenn die Anfrage eine andere Methode als GET, HEAD oder POST verwendet oder wenn die Anfrage benutzerdefinierte Header setzt.
Die Preflight-Anfrage ist eine OPTIONS-Anfrage, die die folgenden Header enthält:
Origin: Der Ursprung der Webseite, die die Anfrage stellt.Access-Control-Request-Method: Die HTTP-Methode, die in der eigentlichen Anfrage verwendet wird.Access-Control-Request-Headers: Eine durch Kommas getrennte Liste der benutzerdefinierten Header, die in der eigentlichen Anfrage verwendet werden.
Der Server antwortet dann mit den folgenden Headern:
Access-Control-Allow-Origin: Der Ursprung, der auf die Ressource zugreifen darf.Access-Control-Allow-Methods: Die HTTP-Methoden, die bei der ursprungsübergreifenden Anfrage erlaubt sind.Access-Control-Allow-Headers: Die HTTP-Header, die bei der ursprungsübergreifenden Anfrage erlaubt sind.Access-Control-Max-Age: Die Anzahl der Sekunden, für die der Browser die Ergebnisse der Preflight-Anfrage zwischenspeichern kann.
Wenn der Server mit den entsprechenden CORS-Headern antwortet, fährt der Browser mit der eigentlichen ursprungsübergreifenden Anfrage fort. Andernfalls blockiert der Browser die Anfrage und löst einen Fehler aus.
Beispiele für die CORS-Konfiguration
Die Implementierung von CORS variiert je nach der serverseitigen Technologie, die Sie verwenden. Hier sind einige Beispiele für gängige serverseitige Sprachen und Frameworks:
Node.js mit Express
Die Verwendung der cors-Middleware ist ein gängiger Ansatz zur Konfiguration von CORS in Node.js mit Express:
const express = require('express');
const cors = require('cors');
const app = express();
// CORS für alle Ursprünge aktivieren
app.use(cors());
// CORS für einen bestimmten Ursprung aktivieren
// app.use(cors({ origin: 'http://example.com' }));
// CORS mit Optionen aktivieren
// app.use(cors({
// origin: ['http://example.com', 'http://localhost:3000'],
// methods: ['GET', 'POST', 'PUT', 'DELETE'],
// allowedHeaders: ['Content-Type', 'Authorization'],
// credentials: true
// }));
app.get('/api/data', (req, res) => {
res.json({ message: 'Hello from the API!' });
});
app.listen(3001, () => {
console.log('Server listening on port 3001');
});
Python mit Flask
Sie können die Flask-CORS-Erweiterung verwenden, um CORS in Flask zu konfigurieren:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
# CORS für alle Ursprünge aktivieren
CORS(app)
# CORS für bestimmte Ursprünge aktivieren
# CORS(app, origins=['http://example.com', 'http://localhost:3000'])
@app.route('/api/data')
def get_data():
return {'message': 'Hello from the API!'}
if __name__ == '__main__':
app.run(port=3001)
Java mit Spring Boot
Spring Boot bietet mehrere Möglichkeiten zur Konfiguration von CORS. Ein Ansatz ist die Verwendung der @CrossOrigin-Annotation:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://example.com") // Spezifischer Ursprung
public class ApiController {
@GetMapping("/api/data")
public String getData() {
return "Hello from the API!";
}
}
// Globale CORS-Konfiguration (mit WebMvcConfigurer):
// @Configuration
// public class CorsConfig implements WebMvcConfigurer {
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**")
// .allowedOrigins("http://example.com", "http://localhost:3000")
// .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
// .allowedHeaders("Content-Type", "Authorization")
// .allowCredentials(true)
// .maxAge(3600);
// }
// }
PHP
In PHP können Sie die CORS-Header direkt in Ihrem Skript setzen:
<?php
header("Access-Control-Allow-Origin: http://example.com");
header("Content-Type: application/json");
$data = array("message" => "Hello from the API!");
echo json_encode($data);
?>
Sicherheitsüberlegungen zu CORS
Obwohl CORS ursprungsübergreifende Anfragen ermöglicht, ist es entscheidend, die Sicherheitsauswirkungen zu verstehen und es korrekt zu implementieren, um Schwachstellen zu vermeiden.
1. Vermeiden Sie die Verwendung von Access-Control-Allow-Origin: * in der Produktion
Die Verwendung des Wildcards * im Access-Control-Allow-Origin-Header erlaubt Anfragen von jedem Ursprung und deaktiviert damit effektiv die Same-Origin-Policy für diese Ressource. Dies kann Ihre API für bösartige Websites anfällig machen, die potenziell Benutzerdaten stehlen oder unbefugte Aktionen durchführen können. Geben Sie stattdessen die genauen Ursprünge an, die auf die Ressource zugreifen dürfen. Wenn Ihre Webanwendung beispielsweise auf example.com gehostet wird und auf eine API auf api.example.com zugreifen muss, setzen Sie den Header auf Access-Control-Allow-Origin: http://example.com.
Globales Beispiel: Stellen Sie sich eine Finanzdienstleistungs-API vor, die Access-Control-Allow-Origin: * setzt. Eine bösartige Website könnte dann im Namen eines angemeldeten Benutzers Anfragen an diese API stellen und möglicherweise ohne dessen Wissen Gelder überweisen.
2. Validieren Sie den Origin-Header auf dem Server
Selbst wenn Sie eine Liste erlaubter Ursprünge angeben, ist es wichtig, den Origin-Header auf dem Server zu validieren, um zu verhindern, dass Angreifer den Ursprung fälschen. Ein Angreifer könnte potenziell eine Anfrage mit einem gefälschten Origin-Header senden, um die CORS-Prüfungen zu umgehen. Um dies zu verhindern, vergleichen Sie den Origin-Header serverseitig mit einer Liste vertrauenswürdiger Ursprünge. Wenn der Ursprung nicht in der Liste ist, lehnen Sie die Anfrage ab.
Globales Beispiel: Betrachten Sie eine E-Commerce-Plattform. Ein Angreifer könnte versuchen, den Origin einer legitimen Storefront nachzuahmen, um auf sensible Kundendaten von der API der E-Commerce-Plattform zuzugreifen.
3. Seien Sie vorsichtig mit Access-Control-Allow-Credentials: true
Wenn Sie Access-Control-Allow-Credentials: true setzen, kann der Access-Control-Allow-Origin-Header nicht auf * gesetzt werden. Es muss ein spezifischer Ursprung sein. Dies liegt daran, dass das Zulassen von Anmeldeinformationen von jedem Ursprung ein Sicherheitsrisiko darstellen kann, da es bösartigen Websites ermöglichen könnte, auf Benutzerdaten zuzugreifen, wenn sie einen Benutzer dazu verleiten können, ihre Seite zu besuchen, während der Benutzer gleichzeitig auf der Zielwebsite angemeldet ist. Diese Einstellung ist wichtig, wenn mit Cookies oder Autorisierungs-Headern gearbeitet wird.
Globales Beispiel: Eine Social-Media-Plattform, die ursprungsübergreifende Anfragen mit Anmeldeinformationen zulässt, erfordert eine sorgfältige Verwaltung, um unbefugten Zugriff auf Benutzerkonten zu verhindern.
4. Konfigurieren Sie Access-Control-Allow-Methods und Access-Control-Allow-Headers ordnungsgemäß
Erlauben Sie nur die HTTP-Methoden und -Header, die für die ursprungsübergreifenden Anfragen notwendig sind. Wenn Sie nur GET- und POST-Anfragen zulassen müssen, erlauben Sie nicht PUT, DELETE oder andere Methoden. Erlauben Sie ebenso nur die spezifischen Header, die Ihre Anwendung benötigt. Zu freizügige Konfigurationen können das Angriffsrisiko erhöhen.
Globales Beispiel: Ein CRM-System sollte nur die notwendigen API-Endpunkte und -Header für autorisierte Drittanbieter-Integrationen freigeben, um die Angriffsfläche zu minimieren.
5. Verwenden Sie HTTPS für eine sichere Kommunikation
Verwenden Sie immer HTTPS für eine sichere Kommunikation zwischen dem Browser und dem Server. HTTPS verschlüsselt die zwischen Browser und Server übertragenen Daten und verhindert so Lauschangriffe und Man-in-the-Middle-Angriffe. Die Verwendung von HTTP kann sensible Daten für Angreifer offenlegen, selbst wenn CORS korrekt konfiguriert ist.
Globales Beispiel: Gesundheitsanwendungen müssen HTTPS verwenden, um Patientendaten zu schützen, die über verschiedene Ursprünge übertragen werden.
6. Content Security Policy (CSP)
Obwohl nicht direkt mit CORS verbunden, ist die Content Security Policy (CSP) ein weiterer wichtiger Sicherheitsmechanismus, der helfen kann, XSS-Angriffe zu verhindern. CSP ermöglicht es Ihnen, eine Whitelist von Quellen zu definieren, aus denen der Browser Ressourcen laden darf. Dies kann helfen zu verhindern, dass Angreifer bösartige Skripte in Ihre Website einschleusen, selbst wenn es ihnen gelingt, andere Sicherheitsmaßnahmen zu umgehen.
Globales Beispiel: Finanzinstitute setzen oft strenge CSP-Richtlinien ein, um die Quellen von Inhalten zu begrenzen, die auf ihren Online-Banking-Portalen geladen werden, und reduzieren so das Risiko von XSS-Angriffen.
Häufige CORS-Probleme und Fehlerbehebung
CORS-Fehler können frustrierend zu debuggen sein. Hier sind einige häufige Probleme und wie man sie behebt:
1. "No 'Access-Control-Allow-Origin' header is present on the requested resource."
Dies ist der häufigste CORS-Fehler. Er zeigt an, dass der Server den Access-Control-Allow-Origin-Header in seiner Antwort nicht zurückgibt. Stellen Sie sicher, dass der Server so konfiguriert ist, dass er die korrekten CORS-Header für den Ursprung der anfragenden Webseite sendet. Überprüfen Sie Ihren serverseitigen Code und Ihre Konfigurationsdateien.
2. "Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
Dieser Fehler zeigt an, dass die Preflight-Anfrage fehlgeschlagen ist. Dies kann passieren, wenn der Server nicht auf OPTIONS-Anfragen antwortet oder wenn der Server einen Fehlerstatuscode (z. B. 404, 500) als Antwort auf die Preflight-Anfrage zurückgibt. Stellen Sie sicher, dass Ihr Server für die Verarbeitung von OPTIONS-Anfragen konfiguriert ist und einen 200 OK-Statuscode zurückgibt.
3. "Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'."
Dieser Fehler tritt auf, wenn Sie versuchen, Anmeldeinformationen (z. B. Cookies) in einer ursprungsübergreifenden Anfrage zu senden und der Access-Control-Allow-Origin-Header auf * gesetzt ist. Wie bereits erwähnt, können Sie den Wildcard * nicht verwenden, wenn Sie Anmeldeinformationen senden. Sie müssen den genauen Ursprung angeben, der auf die Ressource zugreifen darf.
4. Browser-Caching
Browser können CORS-Antworten zwischenspeichern, was zu unerwartetem Verhalten führen kann, wenn sich die CORS-Konfiguration ändert. Um Caching-Probleme zu vermeiden, setzen Sie den Cache-Control-Header in der Antwort auf no-cache, no-store oder max-age=0. Sie können auch den Access-Control-Max-Age-Header verwenden, um zu steuern, wie lange der Browser die Ergebnisse der Preflight-Anfrage zwischenspeichert.
Alternativen zu CORS
Obwohl CORS der Standardweg ist, um ursprungsübergreifende Anfragen zu ermöglichen, gibt es einige Alternativen, die Sie in bestimmten Szenarien in Betracht ziehen können:
1. JSON mit Padding (JSONP)
JSONP ist eine Technik, die den <script>-Tag verwendet, um die Same-Origin-Policy zu umgehen. JSONP funktioniert, indem die JSON-Daten in einen JavaScript-Funktionsaufruf verpackt werden. Der Browser führt dann die JavaScript-Funktion aus und übergibt die JSON-Daten als Argument. JSONP ist einfacher zu implementieren als CORS, hat aber einige Einschränkungen. Es unterstützt nur GET-Anfragen und ist weniger sicher als CORS.
2. Reverse Proxy
Ein Reverse Proxy ist ein Server, der vor Ihrem API-Server sitzt und Anfragen an diesen weiterleitet. Der Reverse Proxy kann so konfiguriert werden, dass er die notwendigen CORS-Header zur Antwort hinzufügt und so die ursprungsübergreifenden Anfragen vor dem Browser verbirgt. Dieser Ansatz kann nützlich sein, wenn Sie keine Kontrolle über den API-Server haben oder die CORS-Konfiguration vereinfachen möchten.
Fazit
Cross-Origin Resource Sharing (CORS) ist ein entscheidender Sicherheitsmechanismus, der es Webseiten ermöglicht, auf Ressourcen von verschiedenen Ursprüngen kontrolliert zuzugreifen. Zu verstehen, wie CORS funktioniert und es korrekt zu implementieren, ist für die Erstellung sicherer und zuverlässiger Webanwendungen unerlässlich. Indem Sie die in diesem Artikel beschriebenen Best Practices befolgen, können Sie CORS effektiv verwalten und Ihre APIs vor unbefugtem Zugriff schützen.
Denken Sie daran, bei der Konfiguration von CORS immer die Sicherheit zu priorisieren. Vermeiden Sie die Verwendung von Wildcards, validieren Sie den Origin-Header und verwenden Sie HTTPS für eine sichere Kommunikation. Indem Sie diese Vorkehrungen treffen, können Sie sicherstellen, dass Ihre Webanwendungen vor Cross-Site-Angriffen geschützt sind.
Dieser umfassende Leitfaden bietet eine solide Grundlage für das Verständnis von CORS. Beziehen Sie sich immer auf die offizielle Dokumentation Ihrer spezifischen serverseitigen Technologie für die aktuellsten Informationen und Best Practices. Bleiben Sie über neue Sicherheitsbedrohungen informiert und passen Sie Ihre CORS-Konfiguration entsprechend an.