All terms
Glossary · Websikkerhed

Websikkerhed: HTTPS, headers og almindelige angreb

De sikkerhedsheaders ethvert website bør sende, de angreb de beskytter mod — XSS, CSRF, clickjacking, SQL injection — og hvordan SPF, DKIM og DMARC stopper domænespoofing.

Sitecheck Team

Websikkerhed for et almindeligt website handler grundlæggende om tre ting: lever alt over TLS, send de rigtige response headers, og validér alt hvad en bruger kan påvirke. Denne side dækker headersene, de angreb de beskytter mod, og de DNS-records der forhindrer andre i at sende mail som dig.

Sitecheck tjekker headersene nedenfor ved hvert scan, så siden fungerer samtidig som forklaring på de fund.

HTTPS og TLS

TLS (Transport Layer Security) krypterer trafik mellem browser og server; HTTPS er HTTP leveret over det. "SSL" er den forældede forgænger — navnet hænger ved, men enhver aktuel opsætning bruger TLS, og du vil have TLS 1.2 som minimum, TLS 1.3 helst.

HTTPS giver tre ting: fortrolighed (ingen læser trafikken), integritet (ingen ændrer den undervejs) og autentifikation (du taler med den rigtige server). Uden det kan ethvert netværk mellem brugeren og dig indsætte scripts eller reklamer, opsamle loginoplysninger eller stille omskrive indhold. Browsere markerer almindelig HTTP som "Ikke sikker", HTTP/2 og HTTP/3 forhandles ikke uden, og det er et bekræftet — om end let — rankingsignal.

  • Redirect al HTTP til HTTPS med en 301, på edge.
  • Automatisér fornyelse. Udløbne certifikater er blandt de mest udbredte selvforskyldte nedbrud, og de tager hele sitet ned på én gang.
  • Begræns udstedelse med en CAA-record, så kun dine valgte CA'er kan udstede.
  • Fjern mixed content — ét enkelt http://-script på en HTTPS-side blokeres af browsere og ødelægger den funktion, det driver.

HSTS — Strict-Transport-Security

HSTS fortæller browseren, at den altid skal bruge HTTPS til et domæne i en angivet periode, og at den skal nægte at lade brugere klikke sig forbi certifikatadvarsler.

Det lukker det hul, en almindelig redirect efterlader: allerførste forespørgsel, før redirecten, sendes stadig over HTTP og kan opsnappes. Når en browser først har set en HSTS-header, opgraderer den hver efterfølgende forespørgsel lokalt.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • Start med en kort max-age og hæv den, når du er sikker. HSTS er svær at fortryde — browsere respekterer den cachede politik, til den udløber, så en fejl spærrer brugere ude fra HTTP i hele den periode.
  • Tilføj kun includeSubDomains, når alle subdomæner kan levere HTTPS, inklusive interne værktøjer og staging.
  • preload sender dit domæne til en liste, der er indbygget i browsere. Læs fjernelsesproceduren, før du indsender; at komme af listen tager måneder.

CSP — Content-Security-Policy

CSP angiver, hvilke kilder browseren må hente scripts, styles, billeder, frames og andre ressourcer fra. Det er det stærkeste værn mod XSS: selv hvis en angriber indsætter et <script>-tag, nægter browseren at køre det, medmindre kilden er tilladt.

  • Rul ud med Content-Security-Policy-Report-Only først og saml violations. At sende en håndhævende politik i blinde ødelægger dit eget site.
  • Foretræk nonces eller hashes frem for 'unsafe-inline'. En politik med 'unsafe-inline' for scripts giver stort set ingen XSS-beskyttelse, og det er den mest udbredte måde, CSP bliver udrullet uden effekt.
  • Sæt object-src 'none' og base-uri 'self' — billigt, og de lukker reelle bypass-muligheder.
  • Brug frame-ancestors til at styre framing; den erstatter X-Frame-Options.

Clickjacking og frame-ancestors

Clickjacking indlæser dit site i en gennemsigtig iframe oven på angriberens egen brugerflade, så offeret tror, det klikker på én ting, men i virkeligheden klikker på en knap på din side — godkender en betaling, ændrer en indstilling, giver en tilladelse.

Løsningen er at nægte at blive framet:

Content-Security-Policy: frame-ancestors 'self'

X-Frame-Options: DENY gør det samme for ældre browsere. Send begge, hvis du har brug for dækningen; frame-ancestors vinder, hvor den understøttes, og er den, der kan tage en liste af tilladte origins.

XSS — Cross-Site Scripting

XSS er, når input styret af en angriber renderes som eksekverbart script i en anden brugers browser. Stored XSS gemmer det i din database, reflected XSS sender det retur fra en URL-parameter, og DOM-baseret XSS rører aldrig serveren.

Konsekvensen er total for den ramte bruger: sessionstyveri, keylogging, handlinger udført i deres navn, opsamling af loginoplysninger på en side, de med rette tror er din.

  • Escape ved output, kontekstafhængigt — HTML, attribut, JavaScript og URL kræver hver sin escaping. At escape ved input er ikke en erstatning.
  • Byg aldrig DOM med innerHTML fra brugerdata. Brug textContent, eller sanitér med et vedligeholdt bibliotek.
  • Moderne frameworks escaper som standard; sårbarhederne kommer fra de bevidste smuthuller (v-html, dangerouslySetInnerHTML).
  • Læg CSP bagved det hele, så en fejl ikke automatisk kan udnyttes.

CSRF — Cross-Site Request Forgery

CSRF narrer en logget ind brugers browser til at sende en tilstandsændrende forespørgsel til dit site fra en side, den ikke forventede — browseren vedhæfter beredvilligt deres cookies, så forespørgslen ser ægte ud.

  • Sæt SameSite=Lax (eller Strict) på session-cookies. Det alene stopper det meste klassisk CSRF.
  • Brug anti-CSRF-tokens til tilstandsændrende forespørgsler, bundet til sessionen og verificeret serverside.
  • Lad aldrig GET ændre tilstand. Et GET, der sletter noget, kan udløses af et <img>-tag.
  • Tjek Origin/Referer på følsomme endpoints som ekstra lag.

SQL injection

SQL injection er, når brugerinput sammensættes ind i en forespørgsel, så en angriber kan ændre dens struktur — læse vilkårlige tabeller, omgå login eller ødelægge data.

Løsningen har været den samme i to årtier, og den virker: parametriserede forespørgsler. Byg aldrig SQL med strengsammensætning, og prøv ikke at sanitere dig ud af det.

  • Brug bundne parametre eller en query builder/ORM, der udsender dem.
  • Giv databasebrugeren mindst mulige rettigheder. En applikationskonto har sjældent brug for DROP.
  • Validér typer og intervaller ved grænsen som ekstra lag.
  • Husk at injection ikke kun er SQL — samme type fejl findes i NoSQL-forespørgsler, shell-kommandoer og LDAP-filtre.

CORS — Cross-Origin Resource Sharing

CORS er en browsermekanisme, der lemper same-origin policy og lader en side på ét origin læse svar fra et andet, når serveren tillader det via Access-Control-Allow-Origin.

Det er værd at være klar om, hvad CORS ikke er: det er ikke adgangskontrol på serveren. Det begrænser, hvad browser-JavaScript må læse; det gør intet for at stoppe en direkte forespørgsel fra curl eller en server. Autentifikation og autorisation skal stadig håndhæves på endpointet.

  • Tillad specifikke origins. Send aldrig request-headeren Origin retur ubetinget — det ophæver hele mekanismen.
  • Access-Control-Allow-Origin: * kan ikke kombineres med credentials, og den begrænsning findes af en god grund. Omgå den ikke.
  • Hold preflight-svar (OPTIONS) cacheable med Access-Control-Max-Age, så du undgår latency på hvert kald.

Referrer-Policy

Referrer-Policy styrer, hvor meget af den aktuelle URL der sendes i Referer-headeren, når en bruger navigerer væk eller henter en ressource.

Standarden lækker mere, end de fleste regner med: fulde URL'er, inklusive stier og query strings, der kan indeholde tokens, søgetermer eller interne id'er, sendes til tredjeparter.

strict-origin-when-cross-origin er den fornuftige standard — fuld URL ved samme origin, kun origin på tværs af origins, og intet ved nedgradering til HTTP. Brug no-referrer på sider med reelt følsomme URL'er.

Permissions-Policy

Permissions-Policy (tidligere Feature-Policy) angiver, hvilke browserfunktioner siden og dens iframes må bruge — kamera, mikrofon, geolokation, betaling og andre.

Den primære værdi er indeslutning: den forhindrer et kompromitteret tredjepartsscript eller en indlejret iframe i stille at anmode om stærke rettigheder. Slå alt fra, du ikke bruger:

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

Email authentication — SPF, DKIM, DMARC

De tre TXT-records forhindrer andre i at sende mail som dit domæne. De arbejder sammen og er tæt på ubrugelige hver for sig.

SPF angiver, hvilke servere der må sende mail for dit domæne. Udgiv præcis én SPF-record, og hold dig under RFC 7208-grænsen på 10 DNS-opslag — hvert include: kan indlejre flere, og overskrides grænsen, fejler SPF.

DKIM signerer udgående beskeder kryptografisk med en privat nøgle, og modtagere verificerer mod en offentlig nøgle i DNS. Brug en separat selector per afsendende udbyder, så du kan rotere én uden at røre de andre.

DMARC binder de to sammen: den fortæller modtagere, hvad de skal gøre, når SPF og DKIM fejler, og hvor rapporter skal sendes hen.

v=DMARC1; p=none; rua=mailto:dmarc@example.com

Rul ud i den rækkefølge, og start på p=none. Det er en overvågningstilstand: den ændrer intet ved leveringen, men sætter rapporterne i gang. Læs dem, til du er sikker på, at hver eneste legitime afsender — dit CRM, faktureringssystem, marketingplatform, helpdesk — består. Først derefter til p=quarantine, og senere p=reject.

At springe direkte til p=reject er den klassiske fejl. Det sender legitim mail fra systemer, du havde glemt, i et sort hul, og du opdager det, når en kunde nævner, at de aldrig fik deres faktura.

Se også