Zum Inhalt springen

Aufgabe 17 - CORS-Fehler nachstellen und sauber beheben

Zu Zen-Modus wechseln

Aufgabe 17 - CORS-Fehler nachstellen und sauber beheben

Abschnitt betitelt „Aufgabe 17 - CORS-Fehler nachstellen und sauber beheben“

Sie erzeugen die häufigsten CORS-Fehler absichtlich, ordnen jede Browsermeldung ihrer tatsächlichen Ursache auf dem Server zu und beheben sie richtig (siehe Kapitel Getrennte Systeme). Die verbreitete Lösung besteht darin, alles zu erlauben. Am Ende dieser Übung wissen Sie, warum das keine Lösung ist, und Sie haben es selbst nachgemessen.

  • Kapitel Getrennte Systeme, Abschnitte Der Browser als Sicherheitsgrenze und CORS im Detail.
  • Zwei kleine Anwendungen auf zwei verschiedenen Ports, etwa localhost:3000 für das Frontend und localhost:4000 für die API. Ein paar Zeilen genügen, das muss nicht Ihr Projekt sein.
  • Browser mit geöffneter Entwicklerkonsole und curl.
  • Sie erklären den CORS-Ablauf mit und ohne Preflight und benennen, was einen Preflight auslöst.
  • Sie ordnen eine CORS-Fehlermeldung im Browser der Ursache auf dem Server zu und prüfen mit curl gegen.
  • Sie begründen, warum CORS keinen Zugriffsschutz darstellt.
  • Reproduktion: Origins vergleichen und einen ersten CORS-Fehler erzeugen (Teil A).
  • Reorganisation und Transfer: Fehlerbilder zuordnen und die Konfiguration richtig aufsetzen (Teil B).
  • Reflexion, Problemlösung und Urteilsbildung: die Grenzen von CORS nachweisen und einordnen (Teil C).

Die Übung ist auf etwa zwei Stunden ausgelegt.

  1. Entscheiden Sie für sechs Adressenpaare, ob sie dieselbe Origin haben, und begründen Sie jede Entscheidung mit dem Teil, der sich unterscheidet. Gehen Sie von https://projekt.example.at aus und vergleichen Sie mit: https://projekt.example.at/bookings, http://projekt.example.at, https://api.projekt.example.at, https://projekt.example.at:8080, https://projekt.example.at:443, https://PROJEKT.example.at.

  2. Starten Sie Ihre beiden Anwendungen. Bauen Sie in die API einen Endpunkt GET /ping, der ein kleines JSON zurückgibt, ohne jede CORS-Kopfzeile.

  3. Rufen Sie den Endpunkt aus dem Frontend im Browser mit fetch auf. Notieren Sie die vollständige Fehlermeldung aus der Konsole.

  4. Rufen Sie denselben Endpunkt mit curl auf. Notieren Sie Statuscode und Rumpf.

  5. Beide Aufrufe haben denselben Server gefragt und unterschiedlich geendet. Erklären Sie in drei bis vier Sätzen, warum. Beantworten Sie dabei, wer die Anfrage abgelehnt hat: der Server oder der Browser.

  6. Sehen Sie im Netzwerk-Tab nach, ob die Anfrage überhaupt beim Server angekommen ist. Notieren Sie das Ergebnis. Es wird Sie in Teil C wieder beschäftigen.

Erzeugen Sie die folgenden vier Fehler nacheinander. Notieren Sie zu jedem drei Dinge: die Meldung im Browser, die Ausgabe der curl-Gegenprobe, und die Änderung am Server, die ihn behebt.

  1. Der Server schickt keinen Access-Control-Allow-Origin-Header.

  2. Der Server beantwortet OPTIONS nicht. Schicken Sie dazu aus dem Frontend ein POST mit Content-Type: application/json. Notieren Sie zusätzlich, warum dieser Aufruf überhaupt einen Preflight auslöst und ein einfaches GET nicht.

  3. Der Server schickt Access-Control-Allow-Origin: * zusammen mit Access-Control-Allow-Credentials: true, und das Frontend ruft mit credentials: "include" auf. Erklären Sie zusätzlich in drei bis vier Sätzen, warum der Browser genau diese Kombination ablehnt und welches Szenario sie ermöglichen würde.

  4. Das Frontend schickt eine eigene Kopfzeile, etwa If-Match, die nicht in Access-Control-Allow-Headers steht.

  5. Verwenden Sie für jede Gegenprobe diesen Aufruf und passen Sie ihn an:

    Terminal-Fenster
    curl -i -X OPTIONS http://localhost:4000/bookings \
    -H "Origin: http://localhost:3000" \
    -H "Access-Control-Request-Method: POST"
  6. Bauen Sie jetzt die richtige Konfiguration: eine Positivliste erlaubter Origins, aus der die tatsächlich angefragte zurückgespiegelt wird. Übernehmen Sie das Beispiel aus dem Kapitel und passen Sie es an Ihre Ports an. Prüfen Sie danach alle vier Fälle erneut.

  7. Ergänzen Sie Access-Control-Max-Age und Vary: Origin. Beschreiben Sie in je zwei Sätzen, was jeder der beiden Header bewirkt und welches Problem ohne ihn entsteht.

  1. Bauen Sie in Ihre API einen Endpunkt, der absichtlich abstürzt und mit Statuscode 500 antwortet, ohne CORS-Kopfzeilen. Rufen Sie ihn aus dem Browser auf und notieren Sie die Meldung.

  2. Beschreiben Sie in vier bis fünf Sätzen, warum diese Meldung in die Irre führt. Beantworten Sie dabei, woran Sie in dieser Lage erkennen, dass Sie nicht an der CORS-Konfiguration schrauben sollten.

  3. Führen Sie den Beweis aus dem Kapitel. Nehmen Sie einen Endpunkt, den Ihr Browser wegen CORS verweigert, und rufen Sie ihn mit curl auf. Notieren Sie beide Ergebnisse nebeneinander.

  4. Beantworten Sie in fünf bis sechs Sätzen, warum Access-Control-Allow-Origin keine Zugangskontrolle ist. Beschreiben Sie dabei genau, wen CORS schützt und wovor, und nennen Sie das Kapitel, in dem die tatsächliche Zugangskontrolle behandelt wird.

  5. Die Same-Origin-Policy verbietet das Lesen der Antwort, nicht das Absenden der Anfrage. Beschreiben Sie in vier bis fünf Sätzen, welcher Angriff aus dieser Asymmetrie folgt. Nennen Sie ein Beispiel mit einer Bank oder einem Webmail-Konto.

  6. Legen Sie die Origin-Tabelle Ihres eigenen Projekts an, mit den Spalten Umgebung, Frontend, API, erlaubte Origins. Drei Zeilen für lokal, Vorschau und Produktion. Legen Sie die Tabelle in docs/architektur.md ab.

  7. Erklären Sie in drei Sätzen, warum die Adresse der Vorschauumgebung nichts in der Origin-Liste der Produktions-API zu suchen hat.

  1. Aus welchen drei Teilen besteht eine Origin?
  2. Was genau verbietet die Same-Origin-Policy, und was erlaubt sie?
  3. Was löst einen Preflight aus? Nennen Sie drei Auslöser.
  4. Warum lehnt der Browser Allow-Origin: * zusammen mit Allow-Credentials: true ab?
  5. Wozu dient Vary: Origin, und was passiert ohne diesen Header?
  6. Warum sieht ein abgestürzter Endpunkt im Browser wie ein CORS-Problem aus?
  7. Warum ist CORS kein Zugriffsschutz, und wie weisen Sie das in zehn Sekunden nach?

Eine Datei protokoll.md mit dem Origin-Vergleich aus Teil A, den vier Fehlerbildern aus Teil B mit Browsermeldung, curl-Gegenprobe und Behebung, sowie den Nachweisen und Antworten aus Teil C. Die funktionierende CORS-Konfiguration mit Positivliste liegt als Code daneben. Die Origin-Tabelle steht in docs/architektur.md.