0%

Origins und Cross-Site-Anfragen · Übung

Origins und Sites

Öffne mini_browser.py. Weiter oben stehen ein paar Konstanten und drei mitgelieferte Hilfsfunktionen, die Kapitel 9 braucht. Darunter stehen die Regeln, und jede löst bisher nur NotImplementedError aus. Führe die Datei im aus:

python mini_browser.py
Each page below is compared with https://reading.example.
The last column: does the session cookie go along when the page posts a form to the reading list?

page                           site                     same origin      same site        cookie sent
https://reading.example        not written yet          not written yet  not written yet  not written yet
https://app.reading.example    not written yet          not written yet  not written yet  not written yet
https://notes.reading.example  not written yet          not written yet  not written yet  not written yet
https://other.example          not written yet          not written yet  not written yet  not written yet

Eine Zeile pro Name, und noch nichts darin. Diese Lektion füllt drei der vier Spalten.

Die Origin als Text

Lektion 1 hat eine in Worten definiert: Schema, Host und . origin_of(url) gibt sie als Text zurück, immer in derselben Form, damit sich zwei Origins mit == vergleichen lassen:

  • das Schema, dann ://, dann der Host: https://reading.example

  • dann : und der Port, außer der Port ist der Standardport des Schemas: http://reading.example:8080

urlsplit(url) liefert dir die Teile. parts.scheme und parts.hostname kommen in Kleinbuchstaben zurück, also braucht HTTPS://Reading.Example keine zusätzliche Arbeit. parts.port ist eine Zahl oder None, wenn die keinen Port nennt. Das mitgelieferte DEFAULT_PORTS enthält 80 für "http" und 443 für "https". Ein Port, der None ist oder dem Standardport entspricht, fällt aus dem Text weg. Jeder andere Port bleibt.

Das Modell kennt http- und https-URLs mit einem Host und sonst nichts. Bei ftp://reading.example/x ist das Schema kein Schlüssel von DEFAULT_PORTS. Bei einem bloßen Pfad wie /books ist parts.hostname gleich None. In beiden Fällen löst origin_of aus.

same_origin(a, b) nimmt zwei URLs und sagt, ob ihre Origins gleich sind.

Eine Site ist gröber

Drei der vier Namen gehören zusammen: reading.example, app.reading.example und notes.reading.example. Die Origin zeigt das nicht. Drei Hosts sind drei Origins.

sind älter als der Schutz der Origins, und sie richten sich nach einer gröberen Einheit. Das Flag SameSite, das du in Kapitel 4 gesetzt hast, vergleicht Sites.

Eine Site ist das Schema plus die registrierbare Domain: der Teil eines Hostnamens, den jemand registriert hat, etwa reading.example. Ein echter Browser findet diesen Teil mit der Public Suffix List, weil manche Namen auf ein Suffix aus mehr als einem Label enden. Ein Label ist ein Stück eines Hostnamens zwischen zwei Punkten. co.uk und github.io sind solche Suffixe, also ist die registrierbare Domain von shop.example.co.uk gleich example.co.uk, drei Labels lang.

Das Modell hat keine solche , und seine Regel ist eine Modellregel: Jeder Name in diesem Kurs endet auf ein Suffix aus einem Label, also ist die Site das Schema plus die letzten zwei Labels des Hosts.

site https://reading.example
+----------------------------------------+
|  origin https://reading.example        |
|  origin https://app.reading.example    |
|  origin https://notes.reading.example  |
+----------------------------------------+

site https://other.example
+----------------------------------------+
|  origin https://other.example          |
+----------------------------------------+

Die drei Hosts, die auf reading.example enden, sind drei Origins innerhalb einer Site, https://reading.example. https://other.example ist eine Origin und eine eigene Site.

https://reading.example, https://app.reading.example und https://notes.reading.example sind

Das Schema gehört zu einer Site, wie es zu einer Origin gehört. Eine Seite, die über einfaches http kam, gehört nicht zur Site der https-Seiten auf demselben Host. Das ist die Regel des Standards, und Chromium wendet sie auf Cookies an. Firefox und Safari behandeln die beiden noch als eine Site, wenn sie entscheiden, ob ein SameSite-Cookie mitgeht. Lektion 3 führt das mit den anderen Unterschieden auf.

Sind http://reading.example und https://reading.example dieselbe Site?

Warum wäre die Zwei-Label-Regel für shop.example.co.uk falsch?

Die Regel hat eine zweite Grenze. Ein Host, der eine oder ein einzelnes Label ist, hat keine registrierbare Domain, und die Zwei-Label-Regel gibt für ihn eine falsche Antwort. Gib dem Modell nie einen solchen Host. Check my work tut es auch nicht.

Was eine Site ignoriert

Eine Site hat keinen Port. https://reading.example:8443 und https://reading.example sind zwei Origins, weil sich die Ports unterscheiden, und eine Site. Also geht site_of nur vom Hostnamen aus: Teile parts.hostname an den Punkten, behalte die letzten zwei Labels mit labels[-2:] und füge sie wieder mit "." zusammen. Setze das Schema und :// davor.

Was gibt diese Zeile aus, wenn die vier Funktionen geschrieben sind?

print(site_of("https://app.reading.example:8443/x"), same_site("https://notes.reading.example", "https://reading.example"), same_origin("https://notes.reading.example", "https://reading.example"))

Deine Aufgabe

Schreibe in mini_browser.py die vier mit dem Kommentar # Write this function in Lesson 2.:

  1. origin_of(url) gibt die Origin als Text zurück und löst für eine URL, die das Modell nicht kennt, ValueError aus.

  2. same_origin(a, b) vergleicht die Origins zweier URLs.

  3. site_of(url) gibt die Site als Text zurück: das Schema, :// und die letzten zwei Labels des Hosts.

  4. same_site(a, b) vergleicht die Sites zweier URLs.

Jede Funktion behält ihren Namen, ihre und ihren Docstring. Ersetze den Kommentar und die Zeile mit raise durch deinen Code. site_of und die beiden same_-Funktionen können jeweils eine Funktion aufrufen, die du kurz davor geschrieben hast.

Führe dann noch einmal python mini_browser.py aus:

page                           site                     same origin      same site        cookie sent
https://reading.example        https://reading.example  True             True             not written yet
https://app.reading.example    https://reading.example  False            True             not written yet
https://notes.reading.example  https://reading.example  False            True             not written yet
https://other.example          https://other.example    False            False            not written yet

Lies die beiden mittleren Spalten von oben nach unten. Nur die Leseliste teilt eine Origin mit sich selbst. Ihre beiden Nachbarn sind andere Origins auf derselben Site, und other.example ist keins von beiden. Um diesen Unterschied zwischen der zweiten und der dritten Spalte geht es im Rest dieses Kapitels.

Klicke dann auf Check my work. Die letzte Spalte wartet auf Lektion 3, die entscheidet, wann ein Cookie mitgeht.

Aufgabe

Schreibe die ersten vier Regeln des Modells in mini_browser.py.

origin_of(url) gibt die einer als Text zurück: das Schema, ://, den Host in Kleinbuchstaben und dann : und den , außer der Port ist der Standardport des Schemas (80 für http, 443 für https). Pfad und Query- fallen weg.

  • origin_of("HTTPS://Reading.Example:443/books?x=1") gibt "https://reading.example" zurück.

  • origin_of("http://reading.example:8080/a") gibt "http://reading.example:8080" zurück.

Für alles außer einer http- oder https-URL mit Host löst sie aus, etwa für "ftp://reading.example/x" oder "/books".

site_of(url) gibt die Site einer URL als Text zurück: das Schema, :// und die letzten zwei Labels des Hosts. Eine Site hat keinen Port.

  • site_of("https://notes.reading.example/page") gibt "https://reading.example" zurück.

  • site_of("http://reading.example:8080") gibt "http://reading.example" zurück.

same_origin(a, b) und same_site(a, b) nehmen jeweils zwei URLs und geben True oder False zurück: ob die beiden dieselbe Origin haben und ob sie dieselbe Site haben.

Führe python mini_browser.py aus und lies die Tabelle.

Klicke dann auf Check my work. Es ruft die vier mit URLs auf, die du nicht gesehen hast: URLs mit Pfad und Query-String, mit Großbuchstaben in Schema und Host, mit ausgeschriebenem Standardport und mit anderen Ports; drei URLs, die origin_of mit ValueError ablehnen muss; Hosts aus zwei, drei und fünf Labels; und Paare, die sich nur im Schema, nur im Port oder nur in einem Label unterscheiden. Es übergibt nie eine oder einen Host aus einem Label. Nichts aus deinem wird bewertet.