In English

Sårbarhet • Artikel

9 april, 2021

Vad är en SQL-injection-attack?


En SQL injection-attack utnyttjar en säkerhetsbrist som har sin grund i att utvecklaren har misslyckats med att isolera extern fientlig information från webbapplikationens inre maskineri. Det gör det möjligt för en angripare att köra kod eller kommandon.

I det här fallet handlar det om att den underliggande databasen, och de anrop som sker mot databasen av webbapplikationen inte skyddas från fientlig information.

Namnet ”SQL injection” kan misstolkas. Även applikationer som använder NoSQL-databaser är sårbara för samma typ av attack, även om det inte är SQL som används i attacken. Hur kan en attack ske?

SQL-injection - ett exempel

Ett tänkbart exempel är en inloggningssekvens. När webbapplikationen skall kontrollera om det angivna användarnamnet och lösenordet är korrekt, kanske SQL-frågan byggs upp på detta osäkra sätt:

‘SELECT * FROM USER_DB WHERE (USERID = ”‘ + $userid + ‘”) AND (PASSWD = ”‘ + $passwd + ‘”)’

I normalfallet blir resultat kanske:

SELECT * FROM USER_DB WHERE (USERID = ”testuser”) AND (PASSWD = ”secret”)

(För att inte göra exemplet onödigt komplext antar vi att lösenorden lagras i klartext. Det får absolut inte ske i en verklig situation!)

Men om nu en angripare matar in ett användarnamn som innehåller tecken som har en innebörd i SQL, som t.ex.

userid = attackuser”) OR (1=1)–

så blir den resulterande SQL-frågan helt annorlunda (understrykning visar attack):

SELECT * FROM USER_DB WHERE (USERID = ”attackuser”) OR (1=1)–”) AND (PASSWD =”secret”)

‘–‘ innebär start av kommentar, och utrycket (1=1) är alltid sant, vilket betyder att (USERID = ”attackuser”) har blivit oväsentligt och lösenordskontrollen har försvunnit genom att den nu tolkas som en kommentar.

I detta fall returneras alla användarposter som finns i databasen. Om inloggningslogiken bara kollar att SELECT-frågan returnerar resultat, men inte hur många, så kan detta betyda att angriparen har loggat in utan att ha konto eller lösenord.

En angripare som vill sabotera, kanske istället sätter:

userid = attackuser”); DROP USER_DB; —

och därmed beordrar databasen att radera USER_DB. Om detta lyckas eller inte beror på vilka rättigheter som används när SQL-frågan utförs.

I dessa exempel lyckas angriparen skjuta in kod som därefter tolkas som legitim SQL-kod och utförs.

Vad leder det till?

Applikationslogiken sätts ur spel. Om SQL-förfrågan utförs med höga rättigheter, kan det leda till att övrigt databasinnehåll läcker eller påverkas.

I en vitt spridd attack för något år sedan använde angripare en SQL-injection-attack på ett mycket vanligt CMS-system. De sköt in fientlig HTML-kod i databasen och ändrade därmed förstasidan på webbplatsen. Besökare blev därefter omdirigerade till en fientlig webbplats som försökte ladda ner skadlig kod till deras datorer.

Hur förhindrar man att SQL-injection-sårbarheter uppstår?

Validera indata i så stor utsträckning som möjligt. Ju tidigare fientlig data kan filtreras bort, desto bättre. I exemplet ovan skulle till exempel användarid förbjudas innehålla specialtecken som har en särskild innebörd i SQL. Detta löser dock inte alltid hela problemet. De programmeringsspråk och frameworks som används kan dock ha funktioner som är avsedda för att underlätta sådan filtrering.

För specifika databaser kan det finnas särskilda rekommendationer. Oracle har t.ex. publicerat ”An Introduction to SQL Injection Attacks for Oracle Developers”.

I många SQL-bibliotek finns möjligheten att ”preparera” SQL-frågor. Den funktionen är egentligen avsedd för frågor som utförs många gånger och där enbart enstaka parametervärden förändras. Genom att ”förkompilera” SQL-koden vinner man tid när många upprepade frågor skall utföras. Samma funktion kan användas för att ”isolera” innehållet i en frågeparameter från SQL-kod.

En liknande funktion finns i SQL vilken kallas för ”stored procedures”. Om den egentliga SQL-frågan implementeras som en ”stored procedure” och indata lämnas över som parametrar, så är de normalt också isolerade.

Båda dessa mekanismer bör dock testas innan de används: det finns exempel där de inte fungerat som det är avsett.

Eventuella sårbarheter kan också begränsas genom att rättighetskonfigurationen göras mycket strikt. Vid inloggning skall t.ex. ingen tillgång till andra databaser eller SQL ges, och rättigheter att modifiera eller ta bort databaser skall absolut inte finnas.

Webbapptester är användbart för verifiera att motåtgärder fungerar som de är tänkta. Men allra bäst är om säkerhetsbrister undviks redan vid utvecklingsprocessen, till exempel via kodgranskning.

Vill du veta mer om just SQL injection?

The Open Web Application Security Project (OWASP) har publicerat ett antal rekommendationer för att förhindra SQL-injection-sårbarheter, eller minimera den effekt de kan ha. Se deras webbsida: https://www.owasp.org/index.php/SQL_Injection

Det finns också hela böcker skrivna i ämnet. En som kan rekommenderas är:
Clarke et. al. : SQL Injection Attacks and Defense (2nd edition) ISBN: 1597499633

Kontakta oss

Vi erbjuder flera kontaktvägar och återkopplar så snart som möjligt. Har du känslig information ber vi dig att maila krypterat.