HTTP protokollen og sikkerhed - eller bare sikkerhed

HTTP protokollen og sikkerhed - eller bare sikkerhed

Igennem de snart 20 år jeg har beskæftiget mig med Internettet og hjemmesider, er sikkerhed noget som er gået fra: https? til https! I slipstrømmen herpå er der kommet en masse teknologier, settings og options og andet gejl, som hjælper slutbrugeren (og værten for hjemmesiden) med at gøre Internettet mere sikkert, men det kan være en noget nærmest uoverskuelig opgave at finde rundt i. Jeg vil i dette indlæg give nogle pointers på hvordan jeg tjekker et site igennem, så jeg eventuel kan rette fejl, eller lave opgaver, som et team derefter kan løfte.

Jeg vil dele det op i to:

  1. browseren

  2. infrastruktur

i gamle dage ville man nok kalde infrastruktur for serveren, men dagens billede af et setup, indeholder som oftest ikke en direkte server, som vi kender dem (en VM eller en fysisk server). Serveren er abstraheret ud, til fordel for et øvre lag, som vi oftest blot kalder for skyen, eller Cloud'en, som indeholder en masse tjenester, som kan hjælpe en med at lave ens webapplikation 1) skalerbar, og 2) mere sikker (eller mindre sikker hvis man ikke laver det ordentligt … Men sådan er det altid: sløseri og hurtige penge, efterlader som oftest sikkerheden på perronen, mens toget kører og bliver bygget "as we go", passageren er typisk den sidste man tænker på i dette henseende).

Browseren

SSL

Do it. Gå ud, og skaft dit et https certifikat, og sæt det gerne op via Lets Encrypt så renew sker automatisk. Du skal ikke give penge for det :)

Grunde til ikke at gøre det:

  1. Jeg har intet at skjule

  2. http er hurtigere fordi der ikke eksisterer et handshake

NEJ!!!!!

Som internettet virker i dag, så skal du aldrig hente blot en resource. Tjek https://www.httpvshttps.com/, og bedøm selv. Husk dog på at http vs https sammenligner HTTP/1.1 vs HTTP/2.0, og 2.0 giver dig nogle få fordele, men det kræver også at du har en https forbindelse. Med andre ord: skal det gå stærk, skal du bruge https, for at køre http/2.0 :) Og hvem vil ikke gerne have noget der kører stærkt og er sikkert? hva? hva? HVA?

via GIPHY

Headers

Oh boi. Der kunne skrives bøger om det, og det er der sikkert gjort. Har dit website styr over alle headers? Jeg vil foreslå dig at tjekke dit site med securityheaders.com, og se hvad score du får. Det smarte ved securityheaders er at sitet giver dig og råd og vejledning i hvad du skal gøre, for at sikrer dit site og slutbrugeren bedre. De typiske headers man ser mangler, er:

  1. CSP

  2. X-Content-Type-Options

  3. Referrer-Policy

Men der er et hav af andre headers som man også skal sætte for at få en god score, og hvem vil ikke gerne have det?

Server, X-Powered og X-Powered-by

Det er altid god skik at fjerne X-Powered-By, og obfuskere Server header'en, og ikke udgive information om den bagvedliggende infrastruktur direkte. Det vil sige: lad vær med at angive at resourcen er serveret pba "ASP.NET version 3.1.11" eller IIS 7.5 på en XP 3.10 boks. Det er unødvendig information som blot giver en eventuel ond person en indsigt ind i dit bagland, som kan hjælpe ham med at penetrerer dit site. Det her er tildels security by obscurity, som oftest ikke er den korrekte måde at lave sikkerhed på, men lige præcis med disse headers, synes jeg det er ok lige at tænke over hvad det er man sender med af information. Som oftest siger jeg efter:

  1. have en WAF foran mit site, såsom Cloudflare. Cloudflare sætter Server til at være Cloudflare, hvilket jeg synes er acceptabelt. Den fortæller ikke noget om den bagvedliggende infratstrukturs detaljer, men den fortæller dog nok om en eventuel origin

  2. strippe Powered-By fuldstændigt: lad vær med at røbe hvad der serverer content. Dette er som oftest kun dejligt at vide, hvis man har en debug session kørende

HSTS

Slå det til, da vi IKKE vil have downgrading af forbindelser eller MITM angreb. Dette gøres typisk med en header, og securityheaders.com vil informere om hvis den ikke er slået til.

Det man gerne vil have er at opfylde hstspreload.org:

  1. Have en root mapping i din DNS

  2. Redirect http://mysite.com til https://mysite.com, som noget af det første

  3. Have et gyldigt certifikat

  4. max-age på din STS header skal være minumum et år

Og læg mærke til at man SKAL have et gyldigt certifikat! Og det skal man blive ved med at have.

Hvis hstspreload.org melder grøn, så kan du submitte din side med det samme. Det vil jeg anbefale at du gøre.

Infrastruktur

WAF

Azure har det, AWS har det, Cloudflare har det: Web Application Firewall. Selve WAF'en kommer altid som et biprodukt af et skjold, som fx Azure tilbyder via Azure Frontdoor, eller Cloudflare tilbyder som en core service: at shielde origin, så du ikke udgiver din origin(s) direkte til browseren, hvilket gør at angrebsvektoren for en eventuel ond person betydelig mindre.

Hvis du blot bruger Cloudflare, men ikke har aktiveret WAF'en, så gør Cloudflare stadig brug af WAF'en, og beskytter dig mod eventuel dDoS angreb, og andre ondsindede angreb, som forsøger at lægge dit site ned.

Den gode ved en sådan service er at de oftest er bygget ovenpå noget infrastruktur, som kan bære massive HTTP requests, fordelt på mange (rigtig mange) edge nodes spredt ud over verden. Det gør at de har meget bedre infrastruktur, til at forbygge en lang række angreb, og det sker mellem sites. Det vil sige, hvis http://site1.com bliver angrebet, så vil https://site2.com højest sandsynlig være beskyttet, og det behøver ikke være målrettet angreb. Jeg har oplevet sites blive angrebet utilsigtet, af enten IP floods, hvor Cloudflare har fanget disse før angrebet nåede origin.

Single point of entry

Du bør binde dit site sammen på en sådan måde at du kun exposer lige præcis de services der skal til for at dit site kører.

Som oftest ser man at man provisionere mange webservices, og binder dem sammen via en reversed proxy, som nginx, eller noget man selv har kodet. Nogen kaldet det en BFF, andre kalder det en API gateway, mens "de gamle" blot kalder det en proxy. Kært barn har mange navne. Det der oftest sker, er at man glemmer at skærme de services som din proxy binder sammen, og kun udstille selve din proxy.

En løsning kunne være at skærme dem af i nogle virtuelle netværk, hvor resourcerne i netværket ikke kan tilgåes direkte udefra. Man skal også tænke på horisontale kald, altså må service A kalde Service B. Hvis man ikke vil have det, skal man yderligere fordele sine services i forskellige subnets.

Det vigtigste er dog at man kun udstiller lige præcis det som må kaldes fra det offentlige internet. Kan man ikke styre ens request flow, så stiller man sig selv i en svær situation, hvis:

  1. man i fremtiden GERNE vil lave throttling, ekstra checks på alle alle reqests, eller route requests anderledes

  2. have et overblik over de forskellige entry points, fra et sikkerhedsmæssig synspunkt

til 1) behøver det ikke nødvendigvis være en ond person som går udenom din proxy, og kalder service A direkte. Det kan være en kollega, eller ekstern partner, som ved at man kan kalde service A, og "gerne lige vil lave et hurtigt udtræk", som ender med at blive permanent.

til 2) behøver det hellere ikke nødvendigvis være en ond person, men blot en IT afdeling som gerne vil have overblikket over entry points og derved også en eventuel angrebsvektor ind i din organisation. Det kan være at IT afdelingen gerne vil have en ISO certificering, og derfor SKAL have overblikket. Hvis de ved at alt som ikke må kaldes direkte, er skærmet af i et netværk for sig, og ikke er exposed direkte til nettet, så kan de koncentrerer sig om de proxies, som rent faktisk er exposed, og lave hardening på dem.

Client certificate (mutual client auth)

En eventuel hardening af forbindelsen mellem en WAF og en proxy og/eller en given webservice, kan åbnes ved at man mellem WAF'en, og den exposede proxy laver client certificate validering. Dette kan også laves mellem din proxy og dine bagvedliggende webservices.

På denne måde sørger man for at trafikken som slipper gennem proxy'en ALTID er trafik som kommer fra WAF'en, og man sørger også for at trafikken som kommer fra din proxy og til bagvedliggende services ALTID kommer fra proxy'en.

Sagt på en anden måde, så lave man trust mellem kalderen og modtageren, om at trafik KUN må komme fra en afsender. Man kan derved undgå at en person kalder udenom:

  1. WAF'en

  2. din proxy

Herved kan man meget bedre styre trafikken ind i din applikation eller din organisation.

Med Cloudflare kan du lave origin pull: man får et certifikat af Cloudflare, som Cloudflare sender med i alle de requests som sker mellem Cloudflare og origin. Du kan på din origin derefter validere og requestet rent faktisk stammer fra Cloudflare, og sende den videre hvis det passer. Passer det ikke, kan du smide requestet væk.

Tager du origin pull (et client certificate), mellem din WAF og din proxy, og smider du på sammen tid dine services i net VNET, og sørger for at trafik ind i din VNET KUN må komme fra din proxy, så stiller du dig meget bedre. Laver du også client certificate validering mellem din proxy og dine bagvedliggende services, så har du et meget godt fundament, til at styre din trafik.

I Azure er det, for så vidt jeg ved, kun APIM'en som understøtter mutual client auth (som er det samme som origin pull i Cloudflare). APIM understøtter det både:

  1. mellem client og til APIM'en

  2. fra APIM'en og til dine backend services

DNS

Man skal altid passe på med hvad man smider i ens DNS records, og man kan nemt expose mere end man lige tror. Lad mig beskrive det med et eksempel.

For at sætte custom hostnames op i Azure, skal man validere at man ejer subdomænet eller domænet. Det kan gøres på tre måder:

  1. et CNAME som peger på den givne webapp

  2. en TXT record som peger på en domain verfication id

  3. en A record som peger på den givne webapp

  4. en TXT record som peger på webapp'ens domæne

bruger man 1, eller 2 er man godt stillet. Man kan ikke lige umiddelbart snuse sig til den bagvedliggende webapps azure url. Bruger man 3) skal man sørge for at man skjuler origin IP'en, ellers har en ond person mulighed for at kalde din webapp direkte, eller blot se IP'en, og derved reverse engineer udfra det. Bruger man 4) kan man via DNS dumpster se URL'en. Forstil dig at en ond person ser følgende TXT record:

  • TXT: my-api1-prod.azurewebsites.net

kan jeg som en ond person prøve mig frem ved at kalde:

  1. my-api2-prod.azurewebsites.net

  2. my-api-staging.azurewebsites.net

etc. Her vil man nok være tilbøjelig til at sige at:

  1. jamen hvis jeg bruger en client certificate, så må jeg godt da den onde person alligevel ikke kan lave et valid request, eller

  2. han kan alligevel ikke hente noget data ud fra websitet, som han ikke allerede kan få andre steder fra

  3. hvad gør det at han kan kalde vore staging miljø?

Man har her misset pointen: man vil gerne skjule denne information, selvom det, på en måde, er security by obscurity. Grundene er:

  • informationen kan man bruge til at omgå WAF'en

  • finde ud af yderligere information omkring den bagvedliggende infrastruktur, og derved afprøve forskellige angreb

Fx hvis jeg ved at kigge på dnsdumpster og securityheaders.com kan se at:

  1. webapplikationen ligger på azure

  2. applikationen er åben for XSS eller MITM

  3. WAF'en kan omgås

  4. webapp'en serveres fra en gammel Joomla eller Wordpress site

  5. webapp'ens staging url ligger på my-webapp-staging.azurewebsites.net (da jeg kan se at et DNS dump giver mig my-web-app-prod.azurewebsites.net) - jeg har blot prøvet mig lidt frem

Kan lave et angreb, som injecter et script ind på staging websitet, som jeg ved nok højest sandsynlig kun besøges af personer i organisationen. Jeg kan derved prøve at komme ind i organisationen den vej. Ikke godt.

Cloudflare

Jeg nævner Cloudflare rigtig mange gange i løbet af artiklen. Det gør jeg af to grunde:

  1. det er et produkt jeg har brugt rigtig meget

  2. den har rigtig mange features samlet et sted

Fx origin pull. Noget som jeg ved Azure Frontdoor eller Azure WAF ikke understøtter.

Cloudflare har også både DNS og WAF samt CDN samlet i et, hvilket jeg godt kan lide. Cloudflare gør et rigtig godt stykke arbejde, med at sikre trafikken. De er ikke de største spillere på markedet, men jeg synes de gør et godt stykke arbejde. Uden nogen affiliate links eller "makkerkode", kan jeg klart anbefale produktet. De har som nogen af de eneste på markedet, flatrate på trafik.

Opsamling: TLDR

  1. brug en WAF

  2. brug et SSL certifikat - eventuel med auto renew via letsencrypt.org

  3. skjul din origin

  4. styr din trafik via client certificates og VNETs

  5. sæt dine headers korrekt op - tjek via securityheaders.com

  6. sæt DNS korrekt op - tjek via dnsdumpster.com

  7. Slå HSTS til for at undgå downgrading eller MITM

Jeg har i dette indlæg snakket en del om sikkerhed, men jeg har ikke været hele paletten rundt. To stort emner jeg ikke har været indeover overhovedet er fysisk og organisatorisk sikkerhed (bare for at nænve to store emner), som kræver et helt andet mindset og implementation, end det at sikre infrastruktur. Jeg har hellere ikke snakket særlig meget om endpoint sikkerhed, som er et helt emne for sig selv.


Næste gang

Næste gang vil jeg vise hvordan man I Azure og via ARM kan sætte VNETs op, for at sikre trafikken, hvis du gerne vil have besked når indlægget kommer ud, så smid mig en privat besked på enten LinkedIn, Twitter eller mail, så sørger jeg for at kontakte dig direkte. Du kan også blot give mig et follow mig på en af de givne platforme.

Du kan også blot svare "ja tak" på LinkedIn (hvis du har fundet indlægget via LinkedIn), eller reply på Twitter (hvis du har fundet indlægget via Twitter), så sørger jeg for at kontakte dig direkte når det næste indlæg i serien er klar.

comments powered by Disqus