Input Validering: Deteksjon og mitigering av sårbarheter

Input Validering: Oppdage sårbarheter

Tidligere har vi skrevet om populære injection-baserte angrepsvektorer og hentet inn en oversikt over hva man skal sjekke av input og i hvilken rekkefølge. Nå er spørsmålet hvor er det disse sårbarhetene sniker seg inn? Hjelper ikke våre moderne rammeverk oss med noe av dette? 

Joda, det er hjelp å få, men mye av dette må utviklerne få på plass selv, ettersom kravene til funksjonalitet dikterer hva man kan, og ikke kan, gjøre. Samt at mye kommer an på kontekst. Selv om rammeverket har innebygd støtte for å hindre forskjellige angrep er det ikke alltid disse er aktivert automatisk eller gjør det akkurat slik du trenger det.  

I denne artikkelen vil vi gjennomgå hvordan du kan oppdage (teste for) noen typer Injection Baserte angrepsvektorer (deteksjon) og hvordan forhindre dem (mitigering). 

Veldig overordnet så kommer sårbarhetene på følgende områder i webapplikasjonene:

  • JavaScript, HTML, CSS
  •  SQL, XML
  • Filsystemer
  • Logger
  •  HTTP

Eksempler nedenfor bygger på OWASP Testing Guide:

1.  XSS

Deteksjon

Benytt for eksempel JUnit, NUnit eller TestNG (m/ Selenium Webdriver) til å sende inn forskjellig JavaScript snutter for å se om de eksekverer. Testene kan utføres både som enhetstester av utviklerne og som funksjonelle tester av tekniske testere. Andre muligheter er statiske kode scannere/lintere som kan teste for kjente sårbarheter som XSS som en del av bygg pipelinen.

  • Lag en liste med forskjellige JS input med, fra vanlig JS til JS enkodet i mange forskjellige varianter.
  • Sett opp XSS tester i JUnit eller TestNG (eller annet preferert test rammeverk) som tester om JS input blir blokkert eller ikke.

Mitigering

Man kan gjøre dette på en Whitelist eller Blacklist måte, hvorav Whitelist godtar ett sett med input og nekter alt annet, mens Blacklist godtar alt utenom det som er spesifisert som forbudt.

Problemet med Blacklisting er at det finnes mange mange forskjellige metoder for å lure inn JavaScript og komme seg forbi et Blacklist filter, samtidig som nye metoder blir oppfunnet. Du vil ikke klare å ta høyde for alt.

  • Benytt liste med attributter/kjennetegn som vi sier er ulovlig. Hvis input kommer med dette så ikke bare trykk godkjent.

Whitelisting slipper bare inn data som samsvarer med hva som er godkjent. Alt annet blir nektet. Dette er tryggere, men fører ofte til corner-cases hvor data som er legitim blir nektet.

  • Sett opp lovlig patterns med RegEx (F.eks. godtar bare bokstaver og tall og noen spesialtegn).
  • Pass på at sjekker mot RegEx patterns sjekker hele input verdien.

Uansett om man velger White- eller Blacklisting implementeres det på følgende måte:

  • Kan gjøres med Java Servlet filters.
  • Lag et filter som detekterer om det er spor av JS i noen av HTTP parametrene. Hvis ja; send generisk feilmelding. Hvis nei; gå videre.
  •  Et slikt filter kan legges som en Maven dependency.

Blacklist og Whitelist Filters er ingen garanti alene. En angriper kan komme forbi ved å enkode input. Derfor er det viktig at man (i mangelen på et godt norsk ord) Canonicalize all input. Canonicalization betyr å konvertere data som kan eksistere i flere formater til et godkjent format. Følgende JavaScript i vanlig format:

                <script>alert(‘pawned’);</script>

Blir seende ut som følgende når den er URL enkodet

                %3Cscript%3Ealert(%E2%80%98pawned%E2%80%99)%3B%3C%2Fscript%3E%20

Eller som følgende med HTML enkoding

                <script>alert(‘pawned’);</script>

Eller kanskje det er nok å bare legge på en tab

                <script  >alert(‘pawned’);</script>

Eller bytte på med store og små bokstaver

                <sCrIpT>alert(‘pawned’);</ScRiPt>

Det finnes mange måter å gjøre dette på. Poenget er at det kan være utfordrende å klare å blackliste alt du ikke vil godta som kan bli tolket som JavaScript. Det for eksempel hende at det som blir sendt inn er dobbel URL enkodet, slik at når du konverterer bare stripper vekk ett lag, men at det underliggende fortsatt kommer seg forbi Blacklist filteret.

%253Cscript%253Ealert%2528%25E2%2580%2598pawned%25E2%2580%2599%2529%253B%253C%252Fscript%253E%2520

Andre måter å komme seg forbi på er å endre fra UTF-8 eller ISO-8859 til UTF-7.

%2BADw-script%2BAD4-alert%28%2BIBg-pawned%2BIBk%29%2BADsAPA-%2Fscript%2BAD4%20

På grunn av sistnevnte angrepsvektor bør web applikasjonen sette en spesifikk Character Encoding som gjelder for hele applikasjonen, og som ikke godtar input av annen character encoding og at alle headere og body verdier er i ett godkjent format.

I tillegg kan utviklere ta i bruk sikkerhets headere i HTTP protokollen som alle moderne browsere støtter. Ved å inkludere headeren X-XSS-Protection.

                X-XSS-Protection: 1; mode=block

Denne vil blokkere siden fra å laste hvis det detekteres spor av XSS. Verdien 1 alene vil sanitere ethvert XSS forsøk og med mode=block vil ikke en gang siden bli lastet. Spring Security (og andre web rammeverk) har støtte for dette og kan gjøre oppsett enkelt, men det må fortsatt gjøres.

En annen header som kan bidra er CSP (Content-Security Policy) som kan forhindre at JavaScript eller linking til utrygge sider får lastes. Med CSP kan man også få på plass varsling «report-uri: …» som genererer rapporter ved deteksjon av ulumske JavaScript eller andre ikke-godkjente datatyper.

Benytt HttpOnly flagget for HTTP Cookies slik at du unngår muligheten for client-side scripts som prøver å aksessere Cookien.

XSS kan også komme fra databasen. En angriper kan laste opp et JavaScript til databasen som blir eksekvert hver gang applikasjonen henter og prøver å inkorporere det i web siden. En gyllen regel er at du kan ikke stole på det du henter fra din egen database. For å forhindre dette anbefales det å bruke et enkoding bibliotek (OWASP Java Encoder Project). 

For mer informasjon om XSS mitigering se OWASP, spesielt XSS Filter Evasion Cheat Sheet eller Java Sanitizer Plugin. 

Les mer: Input Validering: 10 populære Injection-baserte angrepsvektorer

2.  SQL Injection

Deteksjon

Deteksjon av SQL Injection går enkelt ut på å se om input i form av SQL blir tolket/eksekvert som kode.

  • Benytt JUnit e.l. til å sende forskjellig SQL kode i input felter som trigger en database spørring. Applikasjonen må escape og validere input slik at ingen input kan tolkes som logikk.
  • Sett opp tester som sender inn feilaktig SQL eller andre verdier for å generere database feilmeldinger. Hvis det ikke benyttes generiske feilmeldinger så feiler testen.

Mitigering

De fleste moderne språk og rammeverk har et hav av funksjonalitet for å forhindre SQLi. For sanering av input gjelder mye av det samme som ble listet i kapitlet om XSS, men Java, Spring og Hibernate har også løsninger her.

  • Ikke bygg strenger med input-variabler, og stored procedures er ingen løsning det heller. I Java anbefales det å benytte Bind variabler med Prepared Statements.

PreparedStatement ps = new conn.PreparedStatment(«SELECT * FROM hackers WHERE handle= ?»);

ps.setParameter(1, handle);

ps.setExecuteQuery();

3. Command Injection

Command Injection går ikke ut på at angriper sender inn ondsinnet kode, men at angriper klarer å kalle på funksjonalitet i operativsystemet.

Detektering

I webapplikasjoner i dag er det sjelden behov for å bruke funksjonskall direkte på OS , men hvis en applikasjon tar inn bruker input og benytter det for å utføre OS kall f.eks. i et Linux shell, så er input validering uhyre viktig.

Mitigering

I dag finnes det nok funksjonalitet i programmerings APIene til at du skal klare å løse dette uten en slik direkte kobling. Hvis du ikke ser noen annen vei bør du revurdere arkitekturen din.

  • Løsningen er uansett, hvis du må, å kjøre Whitelisting på input som et Filter. Hvis input ikke matcher pattern (benytt RegEx) så nektes input å gå videre til behandling. 
  • Benytte en mapper. La brukers input bli validert, deretter bruk en mapper tabell som sjekker hvilken kommando som brukerens input skal ha eksekvert. På denne måten blir aldri brukers input sendt direkte til OS nivå.

4. Code Injection

I motsetning til Command Injection så sender angriper her inn Kode som han/hun ønsker eksekvert av applikasjonen. Angrepsvektoren er kanskje mer kjent som RCE (Remote Code Execution). Det positive med Code Injection angrep er at de er i dag sjeldne og de er ofte vanskelige å utnytte, men ved et suksessfullt forsøk så er angriper bare begrenset til hva språket kan utføre på systemet. 

Detektering

Code Injection skjer når bruker-data blir sendt inn og blir dynamisk tolket av en kode interpreter. Det enkleste er å sende inn korte logiske kode-uttrykk på input felter via Unit test-caser. Hvis dette blir tolket av kode-interpreteren så er man sårbar. 

  • Konverter input til lovlig format.
  • PHP som benyttet eval() funksjonen med ikke-validert bruker-input var notorisk sårbar for dette i gamle dager.

Mitigering

  • Input validering via whitelist eller blacklist (se avsnitt 1 – XSS)

Sikkerhetstesting gjennom utviklingsløpet

Hvordan utføre sikkerhetstesting gjennom hele utviklingsløpet? Sjekk ut vår guide:

Last ned guiden

 

5. HTTP Response Splitting

En angrepsvektor hvor angriper injecter data inn i HTTP Response headeren. Sårbarheten kan dukke opp hvis applikasjonen trenger bruker-input til å sette header verdier (eks: web applikasjonen har to forskjellige sider som kan lastes basert på bruker ønske). Hvis ikke applikasjonen filtrerer input kan en angriper legge inn sekvensen %0d%0a som er Carriage Return Line Feed som separerer linjer.

CRLF injection forteller at headeren er avsluttet og at neste data segment er body. Dette kan lede til XSS sårbarheter hvor en angriper kan sende inn ondsinnet JavaScript etter to CRLFCRLF kommandoer. Kan også forårsake web cache poisning.

Detektering

Det er som alltid flere måter å teste på.

  • Enhetstester som prøver å inject CRLFCRLF når header verdier settes fra bruker. Testene bør feile hvis man får lov til å sende inn CRLF enkodet i forskjellige versjoner.
  • Manuelle sikkerhetstester som CURL, Zap eller Burp for å teste om applikasjonen godtar CRLF input.
  • Automatiske scanner verktøy som Burp scanner detekterer slike sårbarheter.

Mitigering

Enkleste måten å unngå denne svakheten er å ikke godta bruker-input i Response headere. Hvis du må godta det, så encode input slik at CRLF ikke kan bli tolket som CRLF. Benytter man moderne programmeringsspråk eller rammeverk vil de sannsynligvis ikke godta at CR eller LF i funksjoner som setter HTTP header verdier.

Les mer: Input Validering: Hva innebærer det egentlig?

6. Log Injection

Log Injection er hvor en angriper klarer å sende inn falske log meldinger for å kontaminere loggene, eller i verste fall kunne slette loggene.

Detektering

  • Skriv enhetstester som sender inn CRLF i forskjellige encodings og verifiser at log meldinger kommer på korrekt format (som ikke er default format fra rammeverket).
  • Benytte automatiske scanner verktøy som kan detektere CRLF injection angrep.

Mitigering

  • Encode CRLF characters i alle log meldinger.
  • Benytt CSP (Content Security Policy) med logging til ekstern tjeneste.
  • Konverter input til et godkjent format før det parses og skrives.
  • Valider CSP log meldinger mot godkjent JSON format.
  • Bruk GUIDs på log meldinger.
  • Log meldinger bør være på millisekund nivå slik at rekkefølge av meldinger er korrekt.  

For mer om secure logging, se OWASP ESAPI logging.

7. LDAP Injection

LDAP Injection er angrep hvor applikasjonen konstruerer LDAP uttrykk basert på input fra bruker. Applikasjoner kan samhandle med en LDAP server via spesielle URIer (ofte over port 389). Her kan brukere potensielt legge til, endre, eller fjerne mapperettigheter.

Detektering

  • Enhetstester som forsøker å sende inn ondsinnet input i forskjellige enkodinger.
  • Benytter du LDAP til å autentisere brukere må det være på plass tester som sjekker om bruker-input kan påvirker LDAP uttrykkene.
  • Sett opp enhetstester som kan verifisere at input med potensielt farlige tegn og uttrykk enten escapes eller nektes (husk logging).
  • Bruk automatiske scanner verktøy som Burp.

Mitigering

  • Escape potensielt farlige tegn og uttrykk

o   *, (, ), &, |, =, =>, (*), (|), *), *))), |)….etc.

  • Sett opp enhetstester med mer komplekse uttrykk bygd opp av bruker-input.

8. XPath Injection

Fungerer veldig likt som SQL Injection hvor man kan hindre hele XPath uttrykk fra å eksekveres, og man injecter sin egen logikk som vil bli tolket av XML parseren.

Detektering

  • Enhetstester som sender inn spesialtegn som gjør at man kan endre logikken rundt parsing av input.
  • Benytt automatiske scanner verktøy som Burp e.l.

Mitigering

  • All bruker-input til XPath nå escapes og enkodes til et godkjent format (både på klient og server siden).
  • Benytt parameter-baserte spørringer hvor spørringen er pre-kompilert. Bruker-input til spørringen skal tolkes som paramtere og ikke som logiske uttrykk.
  • Generiske feilmeldinger til klient ved feil.

9. Host Header Injection

Host header forteller hvilken web app som skal prosessere den innkommende HTTP requesten. Angrepet kan brukes til cache poisning eller password reset poisning, men kan også lede til XSS eller tilgang til interne hosts. Cache poisning betyr at du kan sende fremtidige brukere til andre web sider

Detektering

  • Enhetstester som sjekker om bruker kan sette egne verdier i Host og X-Forwarded-Host header.
  • Manuelle sikkerhetstester.
  • Benytte automatiske scanner verktøy.

Mitigering

  • Konverter input verdier til godkjent format.
  • Verifiser request header.
  • Whitelist godkjente domener.
  • Slå av støtte for X-Forwarded-Host.

10. SMTP Header Injection

Hvis en angriper klarer å sende inn egen data til SMTP header kan klare å legge til egne headere som kan lekke epostens innhold eller benyttes til å sende spam.

Detektering

  • Enhetstester som prøver å legge til headere som CC eller BCC i applikasjoner som sender ut e-poster (f.eks. Kontakt Oss seksjonen på web siden).
  • Manuelle tester av applikasjonen med verktøy som Burp eller Zap e.l.
  • Benytt automatiserte scannere.  

Mitigering

  • Konverter input til godkjent format som escaper farlige tegn (ikke godkjenn newline tegn) og enkoder data.
  • Whitelist godkjente tegn for SMTP headere.

11. SSI Injection

Detektering

  • Verifisere om web server støtter SSI (Hvis dette er i bruk av applikasjonen så støtter web server denne funksjonaliteten). Selv om applikasjonen ikke benytter SSI kan allikevel den underliggende web serveren ha støtte enabled.
  • Skriv enhetstester som sender inn spesialtegn som < !  # = / . « – > [a–zA-Z0-9]
  • Skriv enhetstester som sender inn strenger som:

o   <!–#include virtual=/etc/passwd» –>

o   Hvis applikasjonen er sårbar får du med innhold i den dynamiske responsen

  • Benytt automatiske scanner verktøy som Burp e.l.

Mitigering

  • Slå av SSI funksjonalitet på web server hvis du ikke trenger det.
  • Ikke la bruker-input benyttes SSI funksjonaliteten.
  • Valider all input og escape farlige spesialtegn.
  • Konverter innkommende data til et trygt og standardisert format.

Det finnes mange flere måter å avdekke sårbarheter og suspekte hendelser på, f.eks. med Taint Checking, men får bli en blogg for en annen gang. 

Guide: Slik utfører du sikkerhetstesting gjennom utviklingsløpet

Det har aldri vært mer snakk om sikkerhet i IT verdenen enn nå. Men selv om fokus og snakk fra både fagfolk og media om sikkerhet er større enn før, så smeller det også mye mer enn tidligere. Last ned vår guide for å lære hvordan man kan utføre sikkerhetstesting gjennom hele utviklingsløpet:

Last ned guiden her