Det er ikke bare å toggle «input validation: on». Svaret ligger dessverre, som det meste annet innen IT, under «det kommer an på»-kategorien. Vær for streng i input valideringen din og du vil potensielt nekte lovlig og korrekt input. Vær for mild, og du vil slippe inn ondsinnet input som du absolutt skulle vært foruten.
Når skal man gjøre Input Valideringen? Hvor skal man utføre den? Og hva er egentlig gyldig Input?
Alle steder hvor applikasjonen eller serveren utfører handlinger basert på parametre som kommer fra en sluttbruker skal det utføres validering. Det inkluderer parametre som du trodde egentlig var satt av applikasjonen, men som kan endres da de er på reise innom brukerens nettleser og kommer tilbake.
Boken «Secure By Design» av Johnsson, Deogun og Sawano, lister opp fem hovedkategorier for Input Validering:
- Origin – Kommer data fra en legitim avsender?
- Size – Er størrelsen forsvarlig?
- Lexical Content – Har input korrekt characters og encoding?
- Syntax – Er formatet på input korrekt?
- Semantics – Gir dataene som kommer inn mening?
De nevner også at enkle sjekker (eks: sjekke lengde på input) bør utføres tidlig, mens tyngre sjekker som krever koblinger til databaser eller lignende bør utføres senere. Det å sjekke Origin og Størrelse på input går fort og kan gjøres med en gang. Neste steg blir å utføre en Lexical Content sjekk som scanner input. Syntax sjekking kan kreve input parsing (krever CPU og vil potensielt holde en tråd for en stund), og til slutt sjekke om dataen gir noen mening vil muligens kreve en tur til databasen.
Nedenfor vil jeg gjennomgå de fem hovedkategoriene for Input Validering:
1. Origin Validering
Det kan være logisk å sjekke hvor dataene kommer fra før du i det hele tatt gjør noe med den. Det kan være fordi applikasjonen din bare skal godta besøk fra visse land, virksomheter eller personer. Slike sjekker kan være med å avverge eller detektere Distribuerte DoS angrep. Det er primært to måter å sjekke Origin på:
IP adresse
Man konfigurerer applikasjonen til å bare kunne motta Requests fra et sett med endepunkter filtrert på IP adresse(r). Det er viktig å få frem at denne typen sjekker ikke gjøres fra selve applikasjonen, men på nettverknivå.
Dette kan deles inn i to grupper igjen; internet-facing applikasjoner og Internal-only applikasjoner. Internet-facing apps vil ikke kunne kontrolleres på like god måte som Internal-only (Kan hende alle fra hvor som helst skal kunne nå applikasjonen). De interne kan konfigureres til å bare kunne kommunisere med godkjente IP adresser på det interne nettverket.
Dette gir ingen 100% garanti, men kan minimere støy og kreve at en angriper gjør bittelitt mer effort. IP adresser kan bli spoofed og systemer med gyldig IP adresse kan bli kompromittert.
Les mer: Input Validering: 10 populære Injection-baserte angrepsvektorer
Nøkler
Hvis applikasjonen krever at brukere kan komme fra hvor som helst, fungerer ikke teknikken for IP-adresser. Da kan man benytte nøkler. Nøkler kan levers ut til brukere, klienter og systemer for at de skal kunne kommunisere med din applikasjon.
Det finnes mange forskjellige systemer for å sette opp nøkler. Man kan benytte API nøkler, Access Tokens (Oauth2.0, OIDC e.l.), eller sertifikater mm. Tilgangstyring (Autentisering og Autorisering) er et gigantisk tema vi ikker kommer til å gå dypere inn i her.
2. Size Validering
Kontekst dikterer hva som er ansett som «normal» størrelse på input. Det bør settes min- og max-størrelse på hva applikasjonen godtar av input og dette bør sjekkes så tidlig som mulig. Hvis data sendes over HTTP kan man sjekke Content-Length header og Size på innokmmende data. Er det batch input av filer sjekker du hver enkelt filstørrelse.
Altså; sjekk både size på hver request og den totale mengden. Dette gjelder inptut av alle typer: brukerregistreringer med felter som tar inn navn, adresse, telefonnummer, epost, fil-opplastinger, men gjelder også ved system-til-system som sender hverandre data på filer som JSON eller XML e.l.
- Er data over minstekrav?
- Er data under makskrav?
- Er data NotNULL?
Hvis ‘ja’ på alle à Gå videre.
3. Lexical Content
Her sjekker man om mottatt data inneholder forventede tegn og om input er av korrekt encoding. Dette er en mer ressurskrevende sjekk enn de foregående. Lexical scans bryr seg ikke om struktur i dataene. Man kan benytte RegEx regler for å verifisere at mottatt data samsvarer med et Whitelist regelsett.
Man kan spesifisere at <DOCTYPE> er forbudt i XML filer, eller spesifisere at <!ENTITY> taggen er forbudt. På denne måten forhindrer man at XML Parser blir offer for et XXE (XML External Entity) angrep.
4. Syntax
Syntax sjekking verifiserer strukturen i dokumentet. Er XML eller JSON korrekt formatert. Man kan benytte RegEx her også, men på grunn av høy kompleksitet kan det hende du må parse dokumentet og ha applikasjonen gjøre en vurdering. En måte å verifisere integriteten i et dokument på er å benytte Checksums.
5. Semantics
Semantics-sjekker vil validere om input er av korrekt type og innenfor korrekte verdier i henhold til resten av applikasjonen. Slike begrensninger bør finne sted i domene modellen.
Hvordan utføre sikkerhetstesing gjennom hele utviklingsløpet?
Last ned vår guide der sikkerhetsekspert Even Lysen gjennomgår hvordan du kan utføre sikkerhetstesting gjennom hele utviklingsløpet.