Guides 6 min läsning

HTTP-säkerhetsheaders: vad du ska skicka och hur du kontrollerar dem

HSTS, Content-Security-Policy, X-Content-Type-Options, skydd mot inramning, Referrer-Policy och Permissions-Policy: vad var och en gör och ett säkert värde att börja med.

HTTP-säkerhetsheaders är svarsheaders som säger åt webbläsaren att använda skydd som din sajt annars skulle behöva bygga själv: stanna på HTTPS, kör bara skript från källor du litar på, gissa inte filtyper, låt inte andra sajter rama in sidan och dela mindre om var en besökare kom ifrån. Sex headers täcker det mesta: Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options (eller CSP:ns frame-ancestors), Referrer-Policy och Permissions-Policy. De flesta kräver en rad serverkonfiguration. Content-Security-Policy kräver planering, så börja med den i Report-Only-läge.

De sex headersen i korthet

HeaderSkyddar motEtt värde att börja medStrict-Transport-SecurityAnslutningar som nedgraderas till vanlig HTTPmax-age=31536000Content-Security-PolicyInjicerade skript (cross-site scripting)En policy som först testats i Report-OnlyX-Content-Type-OptionsWebbläsare som kör en fil som en annan typnosniffX-Frame-Options eller frame-ancestorsClickjacking via ramarSAMEORIGIN och frame-ancestors ’self’Referrer-PolicyFullständiga adresser som läcker till andra sajterstrict-origin-when-cross-originPermissions-PolicyOanvända webbläsarfunktioner som efterfrågascamera=(), microphone=(), geolocation=()

Strict-Transport-Security (HSTS)

Även med en omdirigering från HTTP till HTTPS gör en besökare som skriver in din domän den första förfrågan över vanlig HTTP, där den kan läsas eller ändras på vägen. HSTS säger åt webbläsaren att använda HTTPS för din domän från och med nu, så länge som max-age anger, i sekunder:

Strict-Transport-Security: max-age=31536000

Börja kort. Webbläsare följer HSTS tills den löper ut, så ett misstag sitter kvar. Prova max-age=300 i några dagar och höj sedan till ett år (31536000).

includeSubDomains gäller regeln för alla underdomäner. Lägg bara till den när alla fungerar över HTTPS, även gamla staging- och e-postservrar.

preload ber om att få domänen inbyggd i webbläsarna via hstspreload.org, vilket kräver en max-age på minst ett år och includeSubDomains. Det tar lång tid att bli borttagen, så se det som permanent.

Webbläsare ignorerar HSTS i svar över vanlig HTTP. Skicka den över HTTPS och håll koll på certifikatet: med HSTS går det inte att klicka sig förbi ett utgånget certifikat.

Content-Security-Policy

En Content Security Policy listar varifrån sidan får läsa in skript, stilmallar, bilder, typsnitt och ramar, och vart formulär får skickas. Om en angripare lyckas få in ett skript på sidan, via ett kommentarsfält eller ett komprometterat plugin, vägrar webbläsaren att köra det om inte policyn tillåter källan. Det är den mest effektiva av de sex och den lättaste att göra fel, eftersom en för strikt policy slår ut din egen analys, chattwidget eller ditt betalformulär.

Börja med Report-Only

Skicka först policyn som Content-Security-Policy-Report-Only. Webbläsaren blockerar ingenting men rapporterar varje överträdelse till adressen i report-uri (eller nyare report-to) och loggar den i konsolen. En utgångspunkt för en sajt som serverar sina egna 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

Klicka runt på sajten, samla in rapporterna under en vecka eller två och lägg till de källor du faktiskt använder, till exempel din analys- eller betalleverantör. När rapporterna bara visar sådant du vill blockera skickar du samma policy som Content-Security-Policy.

Inline-skript: nonces, inte unsafe-inline

En strikt policy blockerar inline-block med <script> och onclick-attribut, eftersom ett injicerat skript ser likadant ut. Lägger du till ’unsafe-inline’ försvinner problemet, och det mesta av skyddet med det. Ge i stället varje svar en slumpmässig nonce, ange den i policyn som ’nonce-…’ och sätt samma värde på dina egna script-taggar; flytta inline-händelsehanterare till skriptfiler. Tagghanterare som injicerar egna skript kräver extra omsorg, eftersom varje tagg de lägger till också måste tillåtas.

X-Content-Type-Options

Webbläsare brukade gissa en fils typ utifrån innehållet när serverns Content-Type såg fel ut. Det gjorde att en uppladdad ”bild” kunde köras som ett skript. X-Content-Type-Options: nosniff stänger av gissandet. Den har ett enda giltigt värde och ingen känd nackdel, så länge din server skickar korrekta innehållstyper, så skicka den i alla svar.

X-Frame-Options och frame-ancestors

Vid en clickjacking-attack visar en annan sajt din sida i en osynlig ram och lurar besökare att klicka på knappar i den. X-Frame-Options: DENY stoppar all inramning, och SAMEORIGIN tillåter bara dina egna sidor. CSP-direktivet frame-ancestors gör samma sak med mer kontroll, till exempel en lista över partnersajter, och har företräde i webbläsare som stöder det. Skicka båda: frame-ancestors för aktuella webbläsare, X-Frame-Options för äldre. Det gamla värdet ALLOW-FROM stöds inte längre, så använd frame-ancestors för allt utöver ditt eget origin.

Referrer-Policy

När en besökare följer en länk berättar webbläsaren för nästa sajt var hen kom ifrån i headern Referer. Utan begränsningar kan det vara hela adressen, inklusive en sökfråga, en återställningstoken eller ett ordernummer i URL:en. strict-origin-when-cross-origin skickar hela adressen inom din egen sajt, bara domänen till andra sajter och ingenting från HTTPS till HTTP. Det är vad aktuella webbläsare gör när headern saknas, men genom att skicka den gör du valet uttryckligt. Använd no-referrer på sidor med privata uppgifter i URL:en, och undvik unsafe-url, som skickar allt överallt.

Permissions-Policy

Permissions-Policy, tidigare Feature-Policy, stänger av webbläsarfunktioner som din sajt inte använder, för sidan och för varje ram som är inbäddad i den. En tom lista, (), betyder att ingen får använda funktionen:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()

Utelämna de funktioner du använder, eller tillåt dem för ditt eget origin med (self), till exempel payment=(self) i en webbutik med en betalknapp.

Headers du kan hoppa över

X-XSS-Protection styrde ett filter som aktuella webbläsare har tagit bort. Utelämna den eller skicka 0.

Expect-CT och Public-Key-Pins är föråldrade. Pinning kunde låsa ute besökare från en sajt, och därför slutade webbläsarna stödja det.

Server och X-Powered-By är inga säkerhetsheaders, men exakta versionsnummer i dem hjälper angripare att välja en exploit. Korta ner dem där din server tillåter det.

Var du ställer in dem

Ställ in headersen på ett ställe, så nära kanten som möjligt: webbservern, CDN:et eller applikationens middleware. I nginx och 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”

Två detaljer i nginx ställer ofta till det. Utan always läggs headersen bara till i lyckade svar, inte på felsidor. Och ett location-block med en egen add_header tappar alla headers från server-blocket, så en enda cache-header för bilder kan i tysthet ta bort dina säkerhetsheaders där. Se också upp med samma header satt två gånger, av servern och av applikationen eller CDN:et: webbläsare hanterar dubbletter olika från header till header, så välj en enda ägare för varje.

Så kontrollerar du dina headers

I en terminal skriver curl -sI https://example.com ut svarsheadersen. Kontrollera även slutadressen efter omdirigeringar, en felsida och en statisk fil, eftersom var och en kan serveras av olika delar av din stack. I en webbläsare visar fliken Network i utvecklarverktygen headersen för varje förfrågan, och konsolen visar CSP-överträdelser.

Eller använd vår kostnadsfria kontroll av HTTP-headers. Den listar varje header en URL skickar efter att ha följt omdirigeringar, markerar vilka av de sex säkerhetsheadersen som saknas, flaggar några värden som tar udden av dem, som en kort max-age för HSTS, en CSP som bara är Report-Only eller unsafe-url, och visar hur sidan cachas och var tiden går åt. Den kontrollerar att headersen finns; den bedömer inte vad en Content Security Policy tillåter, så granska det själv.

Se till att de inte försvinner

Säkerhetsheaders går sällan sönder med buller och bång. De försvinner när en sajt flyttar till en ny server, när man byter CDN, när ett plugin uppdateras eller när någon lägger till ett location-block, och sajten fortsätter att fungera, så ingen märker något. En HTTP-monitor i Uptimechecks upptidsövervakning kan kontrollera svarsheaders vid varje förfrågan, upp till 10 svarskontroller per monitor, till exempel:

Strict-Transport-Security finns.

X-Content-Type-Options är lika med nosniff.

Content-Security-Policy innehåller frame-ancestors.

Alla kontroller måste gå igenom för att monitorn ska räknas som uppe, så en saknad header gör att den går ner, en andra kontroll bekräftar det och du får ett larm. Lägg headerkontrollerna på en egen monitor om du inte vill att de ska påverka sidans upptid. Kontrollerna körs så ofta som varje minut från Stockholm, London och New York; läs hur du övervakar en API-endpoint för att ställa in svarskontroller, och checklistan för webbplatsunderhåll för resten av rutinen.

Få veta samma dag som en header försvinner. Prova Uptimecheck gratis i 14 dagar, inget kreditkort krävs.

Frågor

Vilka HTTP-säkerhetsheaders bör alla webbplatser skicka?

Strict-Transport-Security, X-Content-Type-Options: nosniff, X-Frame-Options eller ett CSP-direktiv med frame-ancestors, Referrer-Policy och Permissions-Policy är enkla att lägga till. Content-Security-Policy ger mest skydd men behöver först testas i Report-Only-läge.

Vad är Content-Security-Policy-Report-Only?

Samma policy som Content-Security-Policy, men webbläsaren rapporterar bara vad den skulle ha blockerat i stället för att blockera det. Använd den för att hitta de källor din sajt faktiskt behöver innan du tillämpar policyn.

Behöver jag fortfarande X-Frame-Options om jag använder frame-ancestors?

Aktuella webbläsare följer frame-ancestors och ignorerar X-Frame-Options när båda finns. Att skicka båda kostar ingenting och skyddar besökare med äldre webbläsare.

Behövs X-XSS-Protection fortfarande?

Nej. Filtret den styrde har tagits bort ur aktuella webbläsare. Utelämna headern eller skicka 0, och förlita dig i stället på en Content Security Policy.

Läs vidare

Guides 6 min läsning

Felbudget: vad det är och hur du använder den

Så räknar du ut en felbudget utifrån en SLO, vad som förbrukar den, hur burn rate fungerar och hur du skriver en felbudgetpolicy som teamet faktiskt följer.

Läs

Driftstopp är historia.

Sätt upp din första övervakning på under en minut, eller ta en titt i livedemon först.

14 dagar gratis · Sedan gratis för 5 övervakningar · Inget kreditkort