HTTP-sikkerhedsheadere er svarheadere, der beder browseren om at bruge beskyttelser, som dit website ellers selv skulle bygge: bliv på HTTPS, kør kun scripts fra kilder, du stoler på, gæt ikke filtyper, lad ikke andre websites vise siden i en frame, og del mindre om, hvor en besøgende kom fra. Seks headere dækker det meste: Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options (eller CSP’ens frame-ancestors), Referrer-Policy og Permissions-Policy. De fleste kræver én linje serverkonfiguration. Content-Security-Policy kræver planlægning, så start den i Report-Only-tilstand.
De seks headere i overblik
HeaderBeskytter modEn værdi at starte medStrict-Transport-SecurityForbindelser, der nedgraderes til almindelig HTTPmax-age=31536000Content-Security-PolicyIndsprøjtede scripts (cross-site scripting)En politik, der først er testet i Report-OnlyX-Content-Type-OptionsBrowsere, der kører en fil som en anden typenosniffX-Frame-Options eller frame-ancestorsClickjacking via framesSAMEORIGIN og frame-ancestors ‘self’Referrer-PolicyFulde adresser, der lækker til andre websitesstrict-origin-when-cross-originPermissions-PolicyUbrugte browserfunktioner, der bliver efterspurgtcamera=(), microphone=(), geolocation=()
Strict-Transport-Security (HSTS)
Selv med en redirect fra HTTP til HTTPS sender en besøgende, der skriver dit domæne, den første forespørgsel over almindelig HTTP, hvor den kan læses eller ændres undervejs. HSTS beder browseren om at bruge HTTPS til dit domæne fra da af, så længe max-age angiver, i sekunder:
Strict-Transport-Security: max-age=31536000
Start kort. Browsere følger HSTS, indtil den udløber, så en fejl hænger ved. Prøv max-age=300 i et par dage, og hæv den så til et år (31536000).
includeSubDomains gælder for alle subdomæner. Tilføj den kun, når de alle, også gamle staging- og mailservere, virker over HTTPS.
preload beder om at få domænet bygget ind i browserne via hstspreload.org, hvilket kræver en max-age på mindst et år og includeSubDomains. Det tager lang tid at blive fjernet igen, så betragt det som permanent.
Browsere ignorerer HSTS i svar over almindelig HTTP. Send den over HTTPS, og hold øje med certifikatet: Med HSTS kan man ikke klikke sig forbi et udløbet certifikat.
Content-Security-Policy
En Content Security Policy angiver, hvorfra siden må indlæse scripts, styles, billeder, skrifttyper og frames, og hvortil formularer må sende data. Får en angriber et script ind på siden, via et kommentarfelt eller et kompromitteret plugin, nægter browseren at køre det, medmindre politikken tillader kilden. Det er den mest effektive af de seks og den nemmeste at få forkert, da en for streng politik ødelægger din egen analyse, dit chatwidget eller din betalingsformular.
Start med Report-Only
Send først politikken som Content-Security-Policy-Report-Only. Browseren håndhæver intet, men rapporterer hver overtrædelse til adressen i report-uri (eller den nyere report-to) og logger den i konsollen. Et udgangspunkt for et website, der serverer sine egne filer:
Content-Security-Policy-Report-Only: default-src ‘self’; script-src ‘self’; style-src ‘self’; img-src ‘self’ data:; font-src ‘self’; object-src ‘none’; base-uri ‘self’; form-action ‘self’; frame-ancestors ‘self’; report-uri /csp-report
Gennemgå websitet, saml rapporterne i en uge eller to, og tilføj de kilder, du faktisk bruger, fx din analyse- eller betalingsudbyder. Når rapporterne kun viser ting, du vil have blokeret, sender du den samme politik som Content-Security-Policy.
Inline scripts: nonces, ikke unsafe-inline
En streng politik blokerer inline <script>-blokke og onclick-attributter, da et indsprøjtet script ser ens ud. Tilføjer du ‘unsafe-inline’, forsvinder problemet, og det meste af beskyttelsen med det. Giv i stedet hvert svar en tilfældig nonce, angiv den i politikken som ‘nonce-…’, og sæt den samme værdi på dine egne script-tags; flyt inline event handlers over i scriptfiler. Tag managers, der indsætter deres egne scripts, kræver ekstra omhu, da hvert tag, de tilføjer, også skal tillades.
X-Content-Type-Options
Browsere plejede at gætte en fils type ud fra indholdet, når serverens Content-Type så forkert ud. Det gjorde det muligt for et uploadet “billede” at køre som et script. X-Content-Type-Options: nosniff slår gætteriet fra. Den har én gyldig værdi og ingen kendte ulemper, så længe din server sender korrekte indholdstyper, så send den i alle svar.
X-Frame-Options og frame-ancestors
Ved et clickjacking-angreb viser et andet website din side i en usynlig frame og narrer besøgende til at klikke på knapper på den. X-Frame-Options: DENY stopper al brug af frames, og SAMEORIGIN tillader kun dine egne sider. CSP-direktivet frame-ancestors gør det samme med mere kontrol, fx en liste over partnerwebsites, og har forrang i browsere, der understøtter det. Send begge: frame-ancestors til nuværende browsere, X-Frame-Options til ældre. Den gamle værdi ALLOW-FROM understøttes ikke længere, så brug frame-ancestors til alt ud over din egen origin.
Referrer-Policy
Når en besøgende følger et link, fortæller browseren det næste website, hvor vedkommende kom fra, i Referer-headeren. Uden begrænsninger kan det være hele adressen, inklusive en søgning, et nulstillingstoken eller et ordrenummer i URL’en. strict-origin-when-cross-origin sender hele adressen inden for dit eget website, kun domænet til andre websites og intet fra HTTPS til HTTP. Det er det, nuværende browsere gør, når headeren mangler, men ved at sende den gør du valget eksplicit. Brug no-referrer på sider med private data i URL’en, og undgå unsafe-url, som sender alt overalt.
Permissions-Policy
Permissions-Policy, tidligere Feature-Policy, slår browserfunktioner fra, som dit website ikke bruger, for siden og for hver frame, der er indlejret i den. En tom liste, (), betyder, at ingen må bruge funktionen:
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
Udelad de funktioner, du bruger, eller tillad dem for din egen origin med (self), fx payment=(self) på en webshop med en betalingsknap.
Headere, du kan udelade
X-XSS-Protection styrede et filter, som nuværende browsere har fjernet. Udelad den, eller send 0.
Expect-CT og Public-Key-Pins er forældede. Pinning kunne låse besøgende ude af et website, og derfor droppede browserne det.
Server og X-Powered-By er ikke sikkerhedsheadere, men præcise versionsnumre i dem hjælper angribere med at vælge et exploit. Skær dem ned, hvor din server tillader det.
Hvor du sætter dem
Sæt headerne ét sted, så tæt på kanten som muligt: webserveren, CDN’et eller applikationens middleware. I nginx og Apache:
# nginx (in the server block)
add_header Strict-Transport-Security “max-age=31536000” always;
add_header X-Content-Type-Options “nosniff” always;
add_header X-Frame-Options “SAMEORIGIN” always;
add_header Referrer-Policy “strict-origin-when-cross-origin” always;
add_header Permissions-Policy “camera=(), microphone=(), geolocation=()” always;
# Apache (.htaccess or virtual host, with mod_headers)
Header always set X-Content-Type-Options “nosniff”
Header always set Referrer-Policy “strict-origin-when-cross-origin”
To detaljer i nginx snyder folk. Uden always bliver headerne kun tilføjet til vellykkede svar, ikke til fejlsider. Og en location-blok med sin egen add_header dropper alle dem fra server-blokken, så en enkelt cache-header til billeder i stilhed kan fjerne dine sikkerhedsheadere der. Hold også øje med den samme header sat to gange, af serveren og af applikationen eller CDN’et: Browsere håndterer dubletter forskelligt fra header til header, så vælg én ejer til hver.
Sådan tjekker du dine headere
Fra en terminal udskriver curl -sI https://example.com svarheaderne. Tjek også den endelige adresse efter redirects, en fejlside og en statisk fil, da hver af dem kan blive serveret af en anden del af din stack. I en browser viser fanen Netværk i udviklerværktøjerne headerne for hver forespørgsel, og konsollen viser CSP-overtrædelser.
Eller brug vores gratis HTTP-header-tjek. Det viser alle headere, en URL sender efter at have fulgt redirects, markerer, hvilke af de seks sikkerhedsheadere der mangler, påpeger nogle værdier, der ophæver dem, fx en kort HSTS max-age, en CSP, der kun er Report-Only, eller unsafe-url, og viser, hvordan siden caches, og hvor tiden går. Det tjekker, at headerne er der; det vurderer ikke, hvad en Content Security Policy tillader, så det må du selv gennemgå.
Undgå, at de forsvinder
Sikkerhedsheadere går sjældent i stykker med et brag. De forsvinder, når et website flytter til en ny server, et CDN skiftes, et plugin opdateres, eller nogen tilføjer en location-blok, og websitet virker stadig, så ingen opdager det. En HTTP-monitor i Uptimechecks oppetidsovervågning kan tjekke svarheadere ved hver forespørgsel, op til 10 svartjek pr. monitor, fx:
Strict-Transport-Security findes.
X-Content-Type-Options er lig med nosniff.
Content-Security-Policy indeholder frame-ancestors.
Alle tjek skal holde, for at monitoren tæller som oppe, så en manglende header får den til at gå ned, et ekstra tjek bekræfter det, og du får en alarm. Læg header-tjekkene på en monitor for sig, hvis du ikke vil have dem til at tælle med i sidens oppetid. Tjekkene kører helt ned til hvert minut fra Stockholm, London og New York; se sådan overvåger du et API-endpoint for opsætning af svartjek og tjeklisten til vedligeholdelse af websites for resten af rutinen.
Find ud af det samme dag, en header forsvinder. Prøv Uptimecheck gratis i 14 dage, uden kreditkort.