cross-site scripting
Slik beskytter du nettstedet mot XSS-angrep
Selv noen av de største aktørene må gang på gang fjerne slike sårbarheter.
I forrige uke ble det kjent at Yahoo nylig har fjernet en alvorlig sårbarhet fra selskapets eposttjeneste. Sårbarheten gjorde det mulig for en angriper å injisere JavaScript-kode i epostmeldinger sendt til Yahoo-adresser. Koden ble kjørt så snart mottakeren åpnet eposten i nettleseren.
Koden gjorde det mulig for angriperen å se innboksen til mottakeren. Men den gjorde det også mulig for angriperen å endre på epostsignaturen til mottakeren, slik at koden kunne spres videre hver gang mottakeren selv sendte en epost.
JavaScript
Sårbarheten som ble utnyttet, er av en svært utbredt type som kalles for Cross-Site Scripting (XSS). I alle hovedsak handler det om å utnytte webapplikasjoners manglende validering av inndata, kombinert med at ikke-klarerte brukerdata, inkludert skriptkode, vises direkte av webapplikasjonen.
Cross-Site Scripting-sårbarheter har nok eksistert helt siden nettleserne fikk JavaScript-støtte og nettsteder begynte å gjengi brukerdata. Men det var trolig først i begynnelsen av 2000 at Cross-Site Scripting ble et begrep, da CERT-divisjonen ved Carnegie Mellon University, i samarbeid med blant annet Apache og Microsoft, publiserte et første sikkerhetsvarsel om denne typen sårbarheter.
Den første artikkelen hvor digi.no omtaler slike sårbarheter i litt detalj, kom i 2002, i forbindelse med at en sikkerhetsforsker lanserte en «gapestokk» med oversikt over nettsteder som lot være å rette kjente Cross-Site Scripting-sårbarheter. På denne tiden ble Cross-Site Scripting forkortet CSS, men dette ble senere endret for å unngå at det ble sammenblandet for forkortelsen til Cascading Style Sheets.
Så hvorfor skrive en artikkel om noe som er så velkjent?
Jo, for til tross for at denne typen sårbarheter nok har eksistert siden JavaScript kom på banen i 1995 og har fått svært mye omtale gjennom store deler av denne perioden, så er XSS-sårbarheter fortsatt svært vanlig.
Svært utbredt
Ifølge Open Web Application Security Project (OWASP) var XSS i 2013 den tredje mest utbredte sårbarhetskategorien på weben, bak (SQL-)injeksjonssårbarheter og sårbarheter som skyldes mangler i brukerautentiseringen og økthåndteringen («session»). OWASP er i gang med en ny undersøkelse, men tallene fra denne har ennå ikke blitt offentliggjort.
Til tross for all den oppmerksomheten XSS-sårbarheter har fått, så er det tydelig at mange utviklere enten ikke er klar over farene ved XSS eller ikke prioriterer det høyt nok å forhindre at slike sårbarheter blir tilgjengelige for angripere.
Selv om man kanskje skulle tro at det å kunne unngå slikt som kapring av brukerøkter, injisering av ondsinnet innhold, videresending av brukere til phishingsider, samt mye annet, er gode nok grunner til å prioritere sikkerhetsarbeidet.
Det finnes automatiserte verktøy for å oppdage XSS-sårbarheter, slik som OWASPs ZAP. Men fordi webapplikasjoner ofte er så forskjellige, kombinert med bruken av tolkning av kode på klientsiden, gjør det ifølge OWASP vanskelig å oppdage alle sårbarheter med automatiserte verktøy. Derfor bør de automatiske verktøyene kombineres med manuell penetrasjonstesting og koderevidering.
Tre hovedvarianter
Generelt skilles det mellom tre ulike typer XSS-angrep.
Lagrede («stored») eller vedvarende XSS-angrep er basert på ondsinnet brukerinnhold som typisk lagres i databasen til webapplikasjonen og vises når andre brukere besøker websider som viser dette innholdet, for eksempel gjennom i innlegg i sosiale medier, kommentarfelt og wikier, for å nevne noe.
I reflekterte, eller ikke-vedvarende XSS-angrep, lagres det ingenting i selve webapplikasjonen. I stedet lokkes brukere til å klikke på lenker som inneholder inndata som umiddelbart blir returnert av webapplikasjonen som en respons på forespørselen.
I begge tilfeller kan en angrepskode bli funnet i responsen av en forespørsel. Men dette gjelder ikke en tredje type XSS-angre, de DOM-baserte (Document Object Model).
I tillegg finnes det DOM-baserte som kun opptrer i DOM, uten at validering og konvertering av inndataene på serversiden kan forhindre angrepet, siden alt skjer på klientsiden, etter at websiden har blitt levert av serveren. En mer omfattende gjennomgang av denne typen XSS-sårbarheter tilbys her av Netsparker, som oppgir at ulike undersøkelser har vist at opptil 50 prosent av alle nettsteder har DOM-baserte XSS-sårbarheter.
Løsninger
For brukerne er det enkelt å unngå å bli utsatt for XSS-angrep. Det er bare å skru av JavaScript-støtten i nettleseren. Men det vil gi en kraftig redusert brukeropplevelse de fleste steder, og mye webinnhold vil fullstendig slutte å fungere. Så deaktivering av JavaScript er lite aktuelt for de fleste.
Det enkleste for en nettstedeier er å la være å gjengi inndata fra brukerne på websidene. Men heller ikke dette er noen aktuell løsning for de fleste.
X-XSS-Protection
Det kanskje enkleste og minst kraftige tiltaket man kan gjøre, er å utstyre websidene med responsheaderen X-XSS-Protection. Denne kan brukes til å aktivere en funksjon for detektering og blokkering av reflekterte XSS-angrep. som finnes i de fleste nettlesere, bortsett fra i Firefox. Den ble først tatt i bruk i Internet Explorer 8, men som det går fram av denne siden, er det ikke innlysende for alle hvilken innstilling man bør bruke.
HTTPOnlyOgså HTTPOnly er et enkelt, men effektivt tiltak for å hindre visse vanlige typer XSS-angrep. Også dette har Microsoft fått æren for. Det har blitt støttet av Internet Explorer siden 2002 og støttes i dag også av de fleste andre nettlesere.
HTTPOnly er et direktiv i Set-Cookie HTTP-headeren som forteller at cookien som settes, ikke skal være tilgjengelig for skripts på klientsiden.
Content Security Policy
CSP (Content Security Policy) er et betydelig kraftigere verktøy som i stor grad kan gjøre det unødvendig å benytte blant annet den nevnte X-XSS-Protection-headeren. Foreløpig er det bare CSP 1.0 som offisielt støttes av de fleste nettlesere, men både versjon 2 og 3 er allerede i ferd med å bli utarbeidet.
Hensikten med CSP er å hindre utnyttelse av flere ulike typer sårbarheter som omfatter injisering av innhold, inkludert XSS.
Men CSP-headere kan man definere hvitelister for hvor ressurser som JavaScript kan lastes fra. For enklere nettsteder kan dette være veldig enkelt. Man stoler på innhold på egen server er trygd å bruke. Kanskje velger man også å inkludere utvalgte, eksterne tjenester, med tilhørende JavaScript og andre ressurser, fra leverandører som Facebook, Twitter, Google og jQuery Foundation.
Forsøk på å inkludere for et eksempel JavaScript fra andre kilder, blir da blokkert av nettleseren.
Content-Security-Policy: default-src 'none'; img-src 'self'; script-src 'self' https://code.jquery.com style-src 'self';
Eksempelet over tillater i utgangspunktet ingen ressurser, men spesifiserer så at bilder og stilsett kan hentes fra eget nettsted, mens skript også kan hentes fra jQuery.
Men dette hjelper lite mot de flere av angrepstypene vi allerede har omtalt, hvor kode injiseres rett inn i HTML-dokumentet.
Blokkering av integrert kode
Heldigvis har CSP enda mer å tilby. I utgangspunktet blokkerer det all JavaScript-kode (og alle CSS-regler) som er som er oppgitt direkte i SCRIPT-elementer i HTML-dokumentet. I stedet må all JavaScript-kode være oppgitt i separate JavaScript-filer, som vanligvis vil være statiske og dermed lite utsatt for injiseringsangrep. Det er mulig å bruke et unsafe-inline-direktiv i CSP-headerne for å åpne for løpende JavaScript-kode (eller CSS-regler) i HTML-dokumentet.
Det er riktignok ikke tilstrekkelig å flytte all JavaScript-kode fra SCRIPT-elementene og over i separate JavaScript-filer. Også alle henvisninger til JavaScript-kode, slik som i events som OnClick og OnKeyUp i for eksempel input-elementer, må også flyttes ut av HTML-dokumentet og over i en JavaScript-fil.
En god gjennomgang av hva og andre egenskaper ved CSP innebærer og kan løses, finnes på denne siden.
Hvilke sikkerhetsheadere som er i bruk av et nettsted, kan testes på denne siden.
Det er likevel ikke slik at CSP er ment som noen førstelinjeforsvar. Tvert imot anbefales det kun brukt som et dybdeforsvar for å redusere skaden som kan oppstå på grunn av injiseringsangrep man ikke har forutsett.
Førstelinjeforsvaret
Det er dessverre slik at for å forsvare seg godt mot XSS, så må man gjøre en innsats, aller helst fra det øyeblikket man begynner å planlegge webapplikasjonen. Først og fremst må man forstå hva XSS er og hvordan det kan skje. Det er ikke bare enkelt, for slike angrep kan skje på mengde ulike måter.
Denne oversikten viser en del av omfanget. Oversikten kan være nyttig for utviklere eller testere som har behov for eksempler de kan bruke under testing av den eventuelle XSS-beskyttelsen i applikasjonen.
Utgangspunktet for forsvar mot XSS-angrep er at man ikke tillater at ikke-pålitelig innhold blir vist i HTML-dokumentet med mindre innholdet har blitt blitt beskyttet ved hjelp av «escaping». Dette gjøres blant annet for å hindre at data går over fra å være dataverdier til å bli tolket som kode. Ikke minst gjeldet dette i forbindelse med bruk av ikke-pålitelig innhold i attributtene til HTML-elementene.
OWASP presenterer på denne siden en rekke sentrale regler for hvordan man kan sikre utdataene mot skadelig kode. Men det betyr ikke at man ikke bør starte forsvaret allerede når dataene kommer inn, for eksempel ved å begrense hva slags tegn som tillates brukt i inndataene, størrelsen på inndataene og formatet på inndataene.
Da har man i alle fall en mulighet til å forhindre at skadelig kode blir ytterligere behandlet av systemet, og ytterligere redusere farene for flere typer angrep, inkludert XSS, men også andre.