SQL Injection
Trodde egentlig dette emnet var dekket godt nok opp i gjennom, men den siste ukas begivenheter viser jo at det fortsatt er et problem "der ute". (Hørte til og med på Radio1 om dette på vei hjem fra jobb igår, men tror kanskje ikke deres forklaring hjalp så mange..). Så her er et forsøk på å forklare dette i all enkelhet, med mottiltak og linker til lesing for de som vil/trenger/bør gå dypere ned i det.
Hva er SQL Injection?
I all enkelhet er dette en angrepsform som benytter seg av ulike websider og applikasjoners søkefelt og lignende felter der brukeren kan skrive inn noe direkte. I et typisk søkefelt blir jo det brukeren skriver inn brukt videre i en SQL streng for å få et søkeresultat ut av databasen. I flere webapplikasjoner må man jo logge seg på med passord og brukernavn også, begge disse feltene valideres opp mot brukere i en database for å sjekke om pålogging er godkjent. Om SQL Injection er mulig kommer an på hvordan teksten fra disse feltene håndteres videre.
Det SQL injection da går ut på er å benytte seg av slike felter der logikken bak ikke sjekker at det brukeren har skrevet inn er trygt å putte direkte inn i en SQL Streng eller har andre mottiltak mot dette. Hvis f.eks brukernavn feltets verdi bare settes direkte inn i SQL strengen som skal validere brukeren åpner dette faktisk for at man kan legge til egne SQL kommandoer og få dem kjørt. Og det er dette som gjør at det kalles SQL Injection. (se eksempel lenger ned)
I bunn og grunn er dette et generelt problem der man pakker et scripting eller programmeringsspråk inn i et annet og brukeren kan bestemme data som benyttes og ikke validerer input strengen for dette språkets Escape Characters. For å ta et banalt og ekstremt eksempel de fleste kan relatere seg til.
- Se for deg et webskjema der du kan velge Command Prompt kommandoer fra en drop down liste og at disse så kjøres på den aktuelle serveren.
- I et felt under kan du velge parametere å gi til kommandoen
- F.eks kan du si du vil kjøre kommandoen Dir fra den statiske lista og så får du lov å angi så mange parametere du vil, f.eks *.exe /s /a osv
- Alle med litt kunnskap om Command Prompt vil da kunne taste inn noe litt annet i parameter feltet, f.eks "& del *.exe /q"
- Her er det And tegnet (&) som gjør at man skiller kommandoer og dermed kan taste inn sin egen.
Prinsippet for SQL Injection er akkurat det samme. Brukeren kan skrive inn et tegn for å avslutte kommandoen og deretter legge inn sin egen kommando og bruke sql serveren til å gjøre ulike ting. Alt fra å kjøre kommandoer mot maskina den kjører på, til å bare gjøre hærverk, dumpe data tabeller f.eks.
Eksempel
Eksempelet som ligger på wikipedia artikkelen om dette er bra, så jeg bruker det også her. Det tar utgangspunkt i en dessverre altfor vanlige måte å håndtere sql og bruker input på, bare ved å slå sammen strengene direkte.
- Du har en nettside med pålogging ved passord og brukernavn. Disse ligger naturlig nok i en database
- Følgende SQL statement benyttes for å hente ut brukerinfo fra basen:
- SELECT * FROM users WHERE name = ' + userName + ';
- Username kommer i dette tilfellet rett fra feltet i et skjema der brukeren skriver det inn
- Om bruker bare skriver inn f.eks Kristian som brukernavn er jo dette helt fint. Men om brukeren benytter seg av litt SQL kunnskap kan man gjøre flere ting.
- F.eks kan brukeren skrive inn følgende i brukernavnfeltet
- a' or 't'='t
- Da vil SQL statementet over se ut som dette når det blir kjørt mot serveren
- SELECT * FROM users WHERE name = 'a' OR 't'='t';
- Dette vil medføre at en gyldig bruker blir valgt ut fordi t alltid vil være lik t og dermed returnere True
- Dette kan jo selvsagt i videre former brukes til å ta over brukerkontoer eller kanskje hele web applikasjonen
- Men, man kan langt enklere gjøre mye hærverk, f.eks ved å sette inn følgende i brukernavn feltet istedet:
- a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '%
- Brukernavn er a og vil antagelig ikke finnes. Men det første semikolonnet her er en escape charater som sier at det kommer en ny kommando etterpå. Og den blir også kjørt. Som du ser sier denne kommandoen at tabellen brukere skal fjernes og neste kommando returnere alle data. Den siste gjør at man potensielt kan få ut alle disse dataene, avhengig av hvordan web app'en er sat opp.
- Og det finnes selvsagt mye annet annet man kunne finne på å taste inn og få kjørt mot basen.
Mottiltak
Først og fremst er det viktig å få med seg at dette gjelder alle SQL servere og i utgangspunktet trenger det ikke være et hull i denne for at man skal kunne utføre SQL Injection angrep. Det er i hvordan SQL statementene bygges opp og hvordan web applikasjonen håndterer disse at hullet evt ligger.
Derimot, om SQL serveren ikke er konfigurert bra eller har sikkerhetshull i tillegg kan man selvsagt utnytte disse også i et slikt angrep. Her kommer også web applikasjonens konfigurasjon inn, det er f.eks viktig hvilke rettigheter dens SQL bruker har.
- Flere språk har ulike funksjoner for å validere input strenger og evt fjerne Escape characters eller lignende. Eller du kan lette lage din egen som gjør dette med et regexp basert replace kall. Dette var en av de første metodene som kom, flere mottiltak eksisterer nå.
- En annen variant er å bygge opp SQL statements litt annerledes, der man ikke putter strengen fra brukeren direkte inn, men bruker sql variable istedet.
- Bruk lagrede prosedyrer/funksjoner i SQL basen til å utføre arbeidet. Disse kan settes opp med "type checking" av input parametere.
- Brukeren kan så settes opp med kun Execute tilgang til de lagrede prosedyrene og kan dermed bare bruke disse. Gjør det langt vanskeligere å få noe ut av SQL injection dersom en angriper finner mulighet for dette i web app'en din.
Les mer om hva SDL sier om sikring mot SQL Injection.
Les mer om Parameterized SQL queries
MSDN sin forklaring på SQL Injection
Hvordan beskytte deg mot SQL Injection i ASP .Net
(Og moralen her er selvsagt at dersom du har ansvaret for ulike web applikasjoner/sider som kan ha denne svakheten, verifiser det og evt rett opp før det blir misbrukt og vil gi deg enda mer ekstra jobb...)