Sikkerhetsheadere – CSP, HSTS og en trygg utrulling
Headere kan begrense hva nettleseren laster og deler, men en kopiert policy kan blokkere skjema, betaling, analyse og innlogging.
Vymo · · 9 min lesing
HTTP-sikkerhetsheadere lar serveren gi nettleseren regler for blant annet skript, innramming, HTTPS og informasjonsdeling. De er et ekstra sikkerhetslag, ikke en erstatning for sikker kode, oppdateringer og god tilgangskontroll.
Den vanskeligste headeren er vanligvis Content-Security-Policy (CSP). En streng og riktig policy kan redusere konsekvensen av kodeinjeksjon. En tilfeldig kopiert policy kan enten være så åpen at den gir liten beskyttelse, eller blokkere nettstedets viktigste funksjoner.
Kortversjonen
For et vanlig nettsted bør dere vurdere:
| Header | Hovedoppgave | Viktigste fallgruve |
|---|---|---|
Content-Security-Policy | Begrense kilder og handlinger i nettleseren | Kopiert policy blokkerer funksjoner eller tillater for mye |
Strict-Transport-Security | Be nettleseren bruke HTTPS i en gitt periode | includeSubDomains aktiveres før alle subdomener støtter HTTPS |
X-Content-Type-Options | Hindre MIME-sniffing med nosniff | Feil Content-Type blir synlig som blokkerte ressurser |
Referrer-Policy | Begrense hvilken kilde-URL som deles | For streng policy fjerner nyttige henvisningsdata |
Permissions-Policy | Slå av eller begrense nettleserfunksjoner | Funksjoner som kamera eller betaling stanses uten test |
X-Frame-Options | Eldre vern mot innramming | Kan komme i konflikt med legitim innbygging |
Start med å kartlegge ressurser og brukerflyter. Innfør deretter en liten, forstått policy, mål brudd og stram gradvis.
Content-Security-Policy
CSP beskriver hvor nettleseren kan hente og utføre ressurser. Direktiver kan blant annet styre skript, stilark, bilder, fonter, rammer, nettverkskall og skjemamål.
En enkel policy for en statisk side uten inline-skript, eksterne ressurser eller innbygging kan se slik ut:
Content-Security-Policy: default-src 'self'; base-uri 'none'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data:; font-src 'self'; script-src 'self'; style-src 'self'; upgrade-insecure-requests
Ikke kopier eksemplet før dere har kontrollert hva siden faktisk bruker. Inline JSON-LD, stilattributter, analyse, videospillere, betalingsvinduer, kart, kundechat og spamvern kan kreve en annen løsning.
Direktiver som bør være eksplisitte
default-src er reserveverdien for flere ressurstyper. Den dekker ikke alle direktiver.
base-uribegrenser om et injisert<base>-element kan endre hvordan relative lenker tolkes.object-src 'none'blokkerer eldre plugin-innhold gjennomobjectogembed.frame-ancestorsbestemmer hvem som kan ramme inn siden, og beskytter mot clickjacking. Den arver ikke fradefault-srcog virker ikke i CSP via meta-element.form-actionbegrenser hvor HTML-skjema kan sendes.script-srcstyrer skript. Dette er den viktigste og ofte vanskeligste delen av en XSS-rettet CSP.connect-srcstyrer blant annetfetch, XHR og WebSocket.frame-srcstyrer hvilke rammer siden selv kan laste. Den er ikke det samme somframe-ancestors.
En policy med default-src 'none' er et godt minsteprivilegium-utgangspunkt når hver nødvendig ressurstype åpnes eksplisitt. For en eksisterende løsning kan default-src 'self' være enklere i første fase, men dere må fortsatt forstå hva som arves og ikke.
Unngå permanent unsafe-inline
'unsafe-inline' i script-src tillater inline JavaScript og reduserer CSP-ens verdi mot skriptinjeksjon betydelig. Det er noen ganger nødvendig som overgang, men bør stå som et dokumentert avvik – ikke som en usynlig permanent løsning.
Tre bedre modeller er:
- Flytt kode til egne filer. Da kan en enkel statisk side ofte bruke
script-src 'self'. - Bruk hash for stabil inline-kode. Hashen må svare nøyaktig til skriptinnholdet, inkludert mellomrom og linjeskift.
- Bruk nonce for dynamiske sider. Serveren lager en uforutsigbar verdi for hver respons, legger den både i CSP og på godkjente skript, og gjenbruker den ikke.
W3Cs Content Security Policy Level 3
anbefaler minst 128 bits kryptografisk tilfeldig verdi før koding for nonce. En bokstavelig {RANDOM} eller samme nonce på alle sider er ikke en sikker implementasjon. En nonce må heller aldri bygges av brukerdata eller et forutsigbart tidspunkt.
En nonce-basert streng policy kan ha denne formen:
Content-Security-Policy: script-src 'nonce-{UNIK_VERDI}' 'strict-dynamic'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'
strict-dynamic gjør at tillit kan følge fra et nonce- eller hash-godkjent skript til skript det laster dynamisk. Det forenkler noen applikasjoner, men betyr også at kode som oppretter skript fra angriperstyrte adresser blir farligere. Gjennomgå derfor all dynamisk skriptlasting.
Kildelister er ikke det samme som tillit
En lang liste over tillatte CDN-er kan se streng ut og likevel gi svak beskyttelse. Dersom en tillatt vert lar brukere laste opp JavaScript, leverer JSONP eller har andre åpne endepunkter, kan en angriper finne en vei gjennom listen.
Tillat eksakte kilder dere trenger. Unngå https:, * og brede wildcard-domener uten en dokumentert grunn. Fjern gamle analyse-, chat- og testkilder når tjenesten avsluttes.
Turnstile, betaling og andre rammer
Eksterne komponenter trenger ofte både skript- og rammetillatelse. Cloudflares gjeldende Turnstile-veiledning krever for eksempel:
script-src https://challenges.cloudflare.com
frame-src https://challenges.cloudflare.com
Verdiene må inngå i resten av deres policy, ikke sendes som et nytt CSP-hode som tilfeldigvis erstatter det gamle. Flere CSP-policyer håndheves samtidig og blir i praksis mer begrensende; de slås ikke sammen til en friere liste.
Cloudflares CSP-veiledning for Turnstile anbefaler nonce-basert CSP3 når løsningen kan generere nonce og sette den på det opprinnelige API-skriptet. Test alltid widget, tokenutstedelse og serverbasert Siteverify etter endringen.
Rull ut CSP uten å stoppe nettstedet
Bruk Content-Security-Policy-Report-Only før en stor håndhevingsendring:
Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; report-to csp
Rapportmodus logger brudd, men blokkerer ikke. Det betyr også at den ikke gir beskyttelsen før håndheving er aktivert.
En trygg rekkefølge er:
- Kartlegg alle side- og skjema-varianter, ikke bare forsiden.
- Registrer ressurser i nettleserens nettverksfane og dagens CSP-brudd.
- Lag en forklarbar policy med minst mulig kilder.
- Kjør rapportmodus i en representativ periode.
- Skill reelle ressurser fra nettleserutvidelser, feil og skannerstøy.
- Fjern unødvendige kilder og bygg om inline-skript med fil, hash eller nonce.
- Håndhev først på en mindre kompleks sidetype eller en kontrollert del av trafikken.
- Test og overvåk etter publisering, med ferdig tilbakeføringsplan.
CSP-rapporter kan inneholde nettadresser og andre detaljer som må behandles forsvarlig. Begrens data, tilgang og oppbevaring. Ikke bygg et rapportendepunkt som selv blir en ny ubegrenset innsendings- eller loggkostnad.
Strict-Transport-Security
HSTS forteller nettleseren at et vertsnavn bare skal brukes over HTTPS i en angitt periode:
Strict-Transport-Security: max-age=31536000
Headeren skal sendes over HTTPS. Nettlesere ignorerer den over HTTP. Start med kortere max-age mens dere tester, og øk når sertifikatfornyelse, videresending og alle relevante tjenester er stabile.
Vurder tilleggene separat:
includeSubDomainsgjelder også alle underdomener. Ett gammelt internt eller eksternt delegert vertsnavn uten HTTPS kan bli utilgjengelig.preloader en forespørsel om å legge domenet i nettleserleverandørenes forhåndsliste. Den krever streng konfigurasjon, og fjerning kan ta tid selv etter at dere har bedt om det.
Ikke bruk HSTS som sertifikatovervåking. Et utløpt sertifikat kombinert med HSTS gjør at brukeren ikke kan klikke seg forbi feilen, slik det skal være; virksomheten må derfor overvåke og fornye sertifikater i tide.
X-Content-Type-Options
Bruk:
X-Content-Type-Options: nosniff
Dette ber nettleseren respektere oppgitt Content-Type i stedet for å gjette innholdstypen. Skript og stilark med feil MIME-type kan da bli blokkert. Rett innholdstypen; ikke fjern nosniff for å skjule en feilkonfigurert server.
Referrer-Policy
Et vanlig balansert valg er:
Referrer-Policy: strict-origin-when-cross-origin
Samme nettsted får hele kildeadressen, mens en annen HTTPS-origin normalt bare får origin og ikke sti eller spørring. Ved overgang fra HTTPS til mindre sikker protokoll sendes ingen referrer.
no-referrer deler ingenting og kan passe der kildeadressen inneholder sensitive opplysninger. same-origin deler bare innen samme origin. Velg den strengeste policyen som fortsatt gir nødvendige analyse- og integrasjonsdata. Sensitive verdier bør uansett ikke ligge i URL-er. MDNs Referrer-Policy-referanse
viser nøyaktig hva hvert alternativ sender.
Permissions-Policy
Permissions Policy kan slå av nettleserfunksjoner siden ikke skal bruke:
Permissions-Policy: camera=(), geolocation=(), microphone=(), payment=(), usb=()
En tom liste betyr at funksjonen ikke tillates. Dersom nettstedet har videosamtale, posisjonsbasert søk eller Payment Request API, må dere lage en smal tillatelse og teste både hovedside og eventuelle iframes.
Ikke kopier en svært lang liste med eksperimentelle direktiver bare for å få et bedre skannerresultat. Ukjente direktiver kan ignoreres og skape konsollstøy. Registrer hva nettleserne dere støtter faktisk forstår.
Vern mot innramming
Den moderne regelen er CSP:
Content-Security-Policy: frame-ancestors 'none'
Hvis nettstedet legitimt skal bygges inn hos seg selv, kan dere bruke 'self' eller en begrenset liste med foreldre. frame-ancestors må sendes i HTTP-header; CSP i et meta-element støtter ikke direktivet.
For eldre klienter kan samme respons også sende:
X-Frame-Options: DENY
Bruk SAMEORIGIN hvis samme origin må kunne ramme inn siden. ALLOW-FROM er foreldet og har utilstrekkelig støtte. Sørg for at gammel og moderne policy uttrykker samme hensikt.
Headere som krever en konkret grunn
Noen kraftige cross-origin-headere skal ikke kopieres til alle nettsteder:
- Cross-Origin-Opener-Policy (COOP) skiller vinduskontekster og kan påvirke popup-baserte innlogginger og betaling.
- Cross-Origin-Embedder-Policy (COEP) kan blokkere eksterne ressurser som ikke uttrykkelig tillater innbygging.
- Cross-Origin-Resource-Policy (CORP) bestemmer hvem som kan laste selve ressursen.
De er viktige for cross-origin-isolasjon og enkelte avanserte nettleserfunksjoner, men krever testing av hele ressurskjeden. De er ikke gratis poeng på en generell headerliste.
CORS-headere som Access-Control-Allow-Origin er heller ikke et universelt sikkerhetstillegg. De gir andre origins tilgang til svar som same-origin-policyen ellers begrenser. Send dem bare på ressurser og metoder som faktisk skal deles.
Informasjonskapsler og sensitiv caching
Session-cookies bør vurderes sammen med headerne:
Set-Cookie: __Host-session=VERDI; Secure; HttpOnly; SameSite=Lax; Path=/
Secure begrenser sending til HTTPS, HttpOnly hindrer vanlig JavaScript-lesing, og SameSite påvirker cross-site-sending. Prefikset __Host- krever blant annet Secure, Path=/ og ingen Domain. Velg Lax, Strict eller None etter reell innloggingsflyt; SameSite=None krever Secure og åpner for cross-site-bruk.
Bruk også riktig Cache-Control på sider med personlige eller sensitive data. En global no-store på alle statiske ressurser skader ytelse uten å gi mening, mens offentlig caching av kontosider kan lekke data. Policyen bør følge innholdstypen.
Ikke bruk utdaterte headere for å pynte på rapporten
Expect-CTer foreldet ; moderne Chromium håndhever Certificate Transparency uten denne headeren.Public-Key-Pins/ HPKP er fjernet fra moderne nettlesere og kunne låse et nettsted ute ved feil.Feature-Policyer erstattet avPermissions-Policymed en annen syntaks.X-XSS-Protectioner en gammel nettleserfunksjon som moderne nettlesere ikke bruker. Flere anbefalinger setter den eksplisitt til0for å unngå problematiske eldre filtre i stedet for å late som den gir moderne XSS-beskyttelse.
Å skjule Server eller rammeverksversjoner kan redusere litt unødvendig informasjon, men det retter ikke sårbar programvare. Prioriter oppdatering og faktisk eksponeringsreduksjon.
Slik tester dere
Se responsen fra den faktiske offentlige adressen, ikke bare fra applikasjonsserveren bak CDN eller proxy:
curl -sSI https://www.eksempel.no/
Test også 301/302-redirecter, 404, API-feil og statiske filer. CDN-er og plattformer kan ha en egen leveransevei som hopper over applikasjonskoden.
I nettleseren bør dere kontrollere:
- konsollen for CSP-, MIME- og Permissions Policy-feil
- nettverksfanen for blokkerte ressurser og redirectkjeder
- innlogging, utlogging og gjenoppretting
- skjema, filopplasting og spamvern
- betaling, kart, video, kundechat og andre iframes
- analyse og samtykkestyring
- mobil- og eldre nettlesere dere faktisk støtter
Eksterne skannere er nyttige for å finne manglende headere, men en toppkarakter viser ikke at CSP-en stopper et realistisk angrep eller at HSTS-konfigurasjonen passer underdomenene. Les den faktiske verdien og test funksjonen.
Vymos egen policy
Per 22. august 2026 sender Vymo samme basisheadere på statiske sider, API-svar og redirecter:
- CSP begrenser standardkilder til egen origin, blokkerer innramming og plugin-innhold, begrenser skjema til egen origin og åpner bare de kjente eksterne kildene for Bootstrap Icons og Cloudflare Turnstile
- HSTS er aktivt i ett år uten
includeSubDomainsog preload før underdomenene er kontrollert nosniff,strict-origin-when-cross-origin, Permissions Policy,X-Frame-Options: DENYogX-XSS-Protection: 0er satt eksplisitt- automatiske tester kontrollerer at policyen for statiske sider og Worker-svar forblir lik
Dagens CSP bruker fortsatt 'unsafe-inline' for skript fordi siden har inline JSON-LD og eksisterende skjemakode. Policyen gir derfor reell begrensning av innramming, skjema, objekter og eksterne kilder, men den er ikke en streng XSS-policy. Neste nivå krever at skjemakoden flyttes eller får nonce/hash, og at JSON-LD får en side-spesifikk hash eller nonce.
Vymos enkle nettsidetilbud har ikke et kundestyrt server- eller headerpanel. Vymo håndterer leveranseoppsettet for siden. Kunder med applikasjoner, nettbutikk, egen innlogging eller tredjepartsskript trenger en egen policy tilpasset den større leveransen.
Les også hvordan HSTS skal innføres uten å låse ute underdomener og hvordan HTTPS og sertifikater faktisk henger sammen .
Har bedriften funnet riktig navn?
Sjekk om .no-domenet er ledig. Et .no-domene koster 199,- per år, også ved fornyelse.