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
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 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.exampledann
: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 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
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.
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
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
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 # Write this function in Lesson 2.:
origin_of(url)gibt die Origin als Text zurück und löst für eine URL, die das Modell nicht kennt,ValueErroraus.same_origin(a, b)vergleicht die Origins zweier URLs.site_of(url)gibt die Site als Text zurück: das Schema,://und die letzten zwei Labels des Hosts.same_site(a, b)vergleicht die Sites zweier URLs.
Jede Funktion behält ihren Namen, ihre 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 ://, den Host in Kleinbuchstaben und dann : und den http, 443 für https). Pfad und Query-
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 "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 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