SQL-injektion: är problemet löst?

SQL-injektion såväl som dess skyddstekniker har inte förändrats mycket under de senaste 20 åren. Är det fortfarande relevant?
Konceptet med SQL-injektion är välkänt. Det finns en populär XKCD-serie om det, som i sin tur inspirerade en dedikerad Bobby Tables-webbplats. Folk har till och med skämtsamt gjort företagsnamn och registreringsskyltar med exploateringssträngar. En sådan nivå av medvetenhet och erkännande betyder säkert att sårbarheten inte längre är relevant, eller hur?


Från MSSQL piggybacking till första plats

SQL-injektion nämndes för första gången (som ”uppbackande SQL-kommandon”) 1998 i Phrack hacker magazine. Liksom andra injektionssårbarheter, aktiveras SQL-injektion genom att programmeraren gör ett fundamentalt misstag – i det här fallet blandar hen ihop karaktären av data och kod. Närmare bestämt infogas indata från användaren (data) i en SQL-fråga (kod) – om användaren är skadlig kan de tillhandahålla noggrant strukturerad input som ändrar koden som exekveras. I fallet med SQL kan detta betyda något så enkelt som att returnera alla poster istället för att använda ett filter, men det kan också potentiellt ändra, infoga eller till och med ta bort element från någon annanstans i databasen. I värsta fall kan det till och med leda till fjärrkörning av kod på servern. SQL-injektion var så utbredd att det snabbt blev en representant för injektionssårbarheter. Som helhet kom ’Injection’ in i OWASP Top Ten 2004 som nummer 6, klättrade till #1 2007 och har hållit fast vid den positionen sedan dess.

Ett spel med \’katt\’ och 'råtta%40%230039%3B

Som med många andra sårbarheter utvecklades SQL-injektionsattacktekniker och försvarsåtgärder ständigt parallellt med varandra i ett katt-och-råtta-spel.

Den ursprungliga begränsningen i Phrack-artikeln föreslog att man skulle citera strängar och undvika citat. Detta implementerades i många API:er vid den tiden, som mysql_escape_string() i PHP. En annan attack för att besegra den här typen av skydd missbrukade hur data översätts över vissa multi-byte teckenkodningar, såsom GBK och UTF-8. Och även om funktionen mysql_real_escape_string() var motståndskraftig mot denna attack, hade den flera andra problem. För det första använder escape-funktioner alltid en inbyggd lista med ”onda” karaktärer som måste escapas. Men angriparen kan kanske utföra en injektion som inte kräver citattecken, som när man riktar in sig på ett kolumnnamn eller numeriskt fält, vilket gör dessa försvar värdelösa. Angriparen kan också använda hex-strängkodning för att dölja citattecken.

Svartlistning var en annan typisk lösning som fortfarande används av webbapplikationsbrandväggar och liknande produkter. Dessa förbjuder helt enkelt vissa karaktärer att komma igenom; Men med smart användning av kodningstrick och SQL-funktioner kan en angripare enkelt komma runt många av dessa skydd. OWASP har några exempel på flykttekniker här.

Naturligtvis, med en så välkänd sårbarhetstyp – som vanligtvis utnyttjas på ett mycket liknande sätt, med endast mindre skillnader baserade på DBMS och plattform – var automatiserad upptäckt och exploatering också oundviklig. Idag finns det många verktyg som automatiskt kan hitta och utnyttja SQL-injektionssårbarheter, till exempel sqlmap. Att upptäcka SQL-injektion i källkoden är också ganska enkelt, eftersom det alltid följer ett mönster för att infoga en sträng som tillhandahålls av användaren direkt i en SQL-frågesträng.

Eftersom SQL-injektion härrör från ett konceptuellt misstag av programmeraren genom att blanda data och kod, har den korrekta lösningen alltid funnits där. Separera SQL-frågan från användarinmatning och använd ett säkert API för att binda användarinmatning till lämpliga fält i frågan. Förberedda satser eller parametriserade frågor – ursprungligen skapade för att förbättra SQL-prestanda med upprepade frågor – kan användas för att realisera detta. Eftersom dessa tekniker förkompilerar den (statiska) satsen och binder användarvariablerna till frågan, kan de förhindra SQL-injektionsproblemet helt. Oavsett vilken typ av knepig sträng angriparen försöker skicka till servern, kommer den bara att behandlas som data i uttalandet.

De good guys har besegrat SQL-injektion – vad nu?

Med en sådan silverkula lösning till hands skulle man förvänta sig att SQL-injektion skulle vara ett problem från det förflutna… tyvärr har det inte varit fallet. Den här webbplatsen har hållit reda på PHP- och MySQL-relaterade frågor och svar publicerade på Stack Overflow som innehöll kodfragment med potentiella SQL-injektioner. Det mest slående resultatet är att andelen frågor och svar med potentiellt sårbar kod verkar ungefär konstant på runt 48-50 % mellan 2008 och 2018 (med mindre fluktuationer), trots en betydande utveckling av skyddsåtgärder! Sökning i NVD ger liknande resultat – SQL-injektion har stadigt utgjort 3-4 % av alla sårbarheter sedan 2014 (med 2016 som en outlier). Även om det aldrig kommer att bli så stort som det var under slutet av 2000-talet, kommer det inte att försvinna snart.

Om något, detta belyser att oavsett hur ”så om ett visst säkerhetsproblem kan se ut vid första anblicken, kommer det att fortsätta att vara ett problem under mycket lång tid om det inte bokstavligen görs omöjligt för programmerare att göra misstaget i första hand. SQL-injektion – och injektionsproblem i allmänhet – är ett mycket viktigt ämne; vi tar upp det på våra kurser. Vårt material diskuterar toppmoderna SQL-injektionsattacktekniker och verktyg samt dess relation till nyare ’NoSQL’-teknologier som Hibernate, MongoDB, DynamoDB och CosmosDB. Ännu viktigare, vi täcker de olika skyddstekniker som är tillgängliga för utvecklare i en mängd olika programmeringsspråk och plattformar.

Relaterade kurser:
Web application security in Java
Security testing Python Web applications
Web application security in Java and C#

information om författaren: