HTTPS
de samme forespørgsler over en krypteret forbindelse
Hvad det er
HTTPS er HTTP sendt gennem en TLS-forbindelse. Forespørgsler og svar er de samme
beskeder som før, med de samme metoder, statuskoder og headere; det, der ændrer
sig, er forbindelsen under dem, som nu er krypteret og autentificeret. Som
URI-skema er https defineret i RFC 9110, specifikationen af HTTP’s semantik
fra juni 2022, der afløste RFC 2818, det korte dokument fra maj 2000, som først
beskrev HTTP over TLS. Standardporten er 443, hvor ren HTTP bruger 80.
RFC 9110 knytter to regler til dette skema. En klient skal kontrollere, at
serverens identitet er en acceptabel match for værten i adressen, hvilket i
praksis betyder, at certifikatet skal dække navnet; en forbindelse til det
forkerte navn er mislykket, uanset hvor stærk krypteringen er. Og
http://example.com/ og https://example.com/ er forskellige origins med hver
sit navnerum. For protokollen deler de et værtsnavn og ellers ingenting.
HTTPS er ikke bundet til én version af HTTP. HTTP/1.1 og HTTP/2 kører over TLS
på TCP. HTTP/3 kører over QUIC, der bærer håndtrykket fra TLS 1.3 inde i selve
transporten, og RFC 9114 udelukker at bruge det til at nå en ren http://-server
direkte, så den nyeste version kommer med HTTPS eller slet ikke.
Hvad krypteringen dækker, ses lettest med en adresse. For
https://shop.example/orders/1234?ref=mail er stien, query-strengen, alle
headere inklusive cookies og Authorization og begge beskedkroppe krypteret.
Netværket mellem den besøgende og serveren ser stadig serverens IP-adresse og
port, trafikkens timing og størrelse og i de fleste forbindelser også
værtsnavnet shop.example: browseren slog det op i DNS, og klienten nævner det i
den første TLS-besked, så én adresse kan betjene mange sites. HTTPS skjuler,
hvad der blev spurgt om, ikke hvem der blev spurgt.
Hvorfor det betyder noget
Det åbne spørgsmål for et offentligt site er, om noget overhovedet stadig skal
svare på http://, og browserne træffer nu det meste af den beslutning selv.
Det første håndtag er den sikre kontekst (secure context), W3C’s betegnelse for
en side, der er leveret over HTTPS eller fra maskinen selv. Browsere forbeholder
en voksende række funktioner til sikre kontekster. Service workers er en af dem:
navigator.serviceWorker er erklæret til sikre kontekster, så på en side hentet
over ren HTTP findes egenskaben simpelthen ikke, og det gør alt, der bygger på
den, heller ikke, med offline-caching som det første. Specifikationen Secure
Contexts anbefaler også, at forfattere af nye specifikationer beskytter følsomme
funktioner på samme måde, så begrænsningen er udgangspunktet for nyt arbejde
frem for en undtagelse fra sag til sag.
Det andet håndtag er blandet indhold (mixed content). Når en side selv er HTTPS,
sorterer browseren hver af dens hentninger efter W3C’s regler for blandet
indhold. Billeder, lyd og video, der hentes over http://, opgraderes
automatisk til https:// og fejler, hvis den adresse ikke svarer. Scripts,
stylesheets og dataforespørgsler blokeres helt med en netværksfejl. Én overset
ukrypteret adresse i en skabelon kan derfor slå en hel funktion ud, ikke bare et
billede.
Så er der meget lidt tilbage til port 80. En lytter, der besvarer hver
forespørgsel med en permanent omdirigering til samme sti på https://, gør
stadig nytte, fordi folk skriver navne uden skema, og gamle links stadig siger
http://. Certifikatudstederens HTTP-udfordring ankommer også dér, når et
certifikat udstedes eller fornyes. HSTS lader derefter en tilbagevendende
browser springe selv omdirigeringen over. Alt ud over de opgaver på port 80 er
en side, der serveres uden garantierne ovenfor.
Loopback er den eneste faste undtagelse for almindelige sites. Specifikationen
regner localhost, 127.0.0.1 og ::1 for potentielt troværdige, så en side
fra udviklerens egen maskine får funktionerne fra sikre kontekster uden et
certifikat. Den bekvemmelighed for udviklere er kilden til en af fejlene
nedenfor.
Sådan ser det ud i praksis
Virksomhedens eget site følger den regel. På produktionsværten
besvarer Caddy hver webforespørgsel og fornyer selv HTTPS-certifikatet
fra Let’s Encrypt, så det er webserverens opgave at holde certifikatet gyldigt
og ikke en persons. De samme sider udgives som en Tor onion-tjeneste, og den
adresse begynder med http:// med vilje. Kolofonen forklarer hvorfor:
onion-adressen er selve tjenestens offentlige nøgle, så Tor-kredsløbet er
autentificeret og krypteret, før der udveksles et eneste ord HTTP, og et
certifikat ville ikke bevise mere om navnet, end adressen allerede gør. Samme
side linker til Qualys SSL Labs, der bedømmer den levende HTTPS-opsætning for
alle, der spørger.
Kundearbejde viser reglen om sikre kontekster fra den anden side. Til en platform, hvis brugere ofte er søfolk og feltpersonale på telefoner, tit uden forbindelse, leverede virksomheden fuld understøttelse af Progressive Web App med en service worker, der cacher skrifttyper, billeder, lyd, video og CDN-ressourcer efter cache-first-princippet. Fordi service workers kun fungerer ordentligt over HTTPS, blev offline- og installationsadfærden testet over HTTPS på rigtige enheder i stedet for at blive taget for givet. Det samme behov viser sig i værktøjerne til et monorepo på mange sprog med 578 task-mål, hvor det go-task-lag, virksomheden skrev, sætter en HTTPS-variant til test af PWA og mobil ved siden af udviklingstilstandene native og Docker.
Hvor det går galt
Scripts holder op med at køre efter skiftet til HTTPS, og nogle billeder
forsvinder. Siderne indeholder stadig http://-adresser, hårdkodet i en
skabelon, gemt i CMS-indhold eller indsat med et tredjepartsuddrag. Browseren
blokerer scripts og stylesheets og opgraderer billederne, som så går i stykker
der, hvor den anden vært mangler HTTPS. Browserkonsollen nævner hver blokeret
adresse. Søg i skabelonerne og det gemte indhold efter det gamle skema, og skriv
hvert fund om til https:// eller til en sti relativt til sitet:
grep -rnE '(src|href)="http://' templates/ content/
En Content-Security-Policy: upgrade-insecure-requests-header bærer siderne
gennem oprydningen, men lader de gemte adresser være, som de var.
Sitet omdirigerer til sig selv, indtil browseren giver op. Et CDN eller en
load balancer terminerer TLS og sender forespørgslen videre til applikationen
over ren HTTP. Applikationen ser http, omdirigerer til https, proxyen sender
det nye forsøg videre som http igen, og løkken ender i en fejl om for mange
omdirigeringer. Samme blindhed får applikationen til at bygge absolutte links,
der begynder med http://. Proxyen skal give det oprindelige skema videre, i
standardheaderen Forwarded: proto=https fra RFC 7239 eller i den ældre
X-Forwarded-Proto, og applikationen bør kun tro på headeren, når den kommer
fra proxyens egen adresse, for enhver klient kan sende den. Lad derefter ét lag
eje omdirigeringen, normalt det, der har certifikatet.
En sessionscookie, der er sat over HTTPS, rejser ukrypteret. RFC 9110
advarer om, at cookies ikke respekterer den grænse, den trækker mellem de to
origins. Efter cookiereglerne i RFC 6265 sendes en cookie uden attributten
Secure også med ukrypterede http://-forespørgsler til samme vært. En
besøgende, der skriver navnet uden skema, er nok til at sende den, og det samme
er en angriber på netværket, der besvarer en hvilken som helst anden ukrypteret
forespørgsel med en omdirigering til sitets http://-adresse. Sæt Secure på
hver cookie, sitet udsteder, og tilføj HSTS, så browseren aldrig sender den
ukrypterede forespørgsel.
Service workeren kører på den bærbare og mangler på telefonen. Udvikleren
åbner http://localhost:3000, en sikker kontekst, og alt virker. Telefonen på
samme netværk åbner http://192.168.1.20:3000, som ikke er en sikker kontekst,
så navigator.serviceWorker er undefined, et bibliotek, der tjekker efter
den, springer registreringen over, og offlinetilstanden mangler uden en lyd.
Server også udviklingsbuildet over HTTPS. Caddy udsteder for eksempel
certifikater til lokale navne og IP-adresser fra sin egen lokale
certifikatudsteder og forsøger at lægge roden i maskinens tillidslager. Dens
dokumentation advarer om, at det trin ikke er garanteret, og at det er
administratorens opgave at få roden ind i alle tillidslagre, og en testtelefon
skal have roden installeret i hånden.
Læs mere
- RFC 9110, afsnit 4.2.2: https URI Scheme — https som URI-skema, dets standardport og reglen om, at en klient skal kontrollere serverens identitet.
- Secure Contexts — hvilke sider der regnes for sikre, hvorfor loopback er med, og rådet om at begrænse nye funktioner.
- Mixed Content — hvilke forespørgsler fra en HTTPS-side der opgraderes, og hvilke der blokeres.
- RFC 7239: Forwarded HTTP Extension — standardheaderen, som en proxy bruger til at give det skema videre, den besøgende brugte.
- Automatic HTTPS — Caddys egen beskrivelse af dens certifikater, dens omdirigering fra HTTP og dens lokale certifikatudsteder.