Artikelen » Server-Side scripting » Artikel
SQL injections
02-10-2009 10:15
SQL injection
Voorbeeld #1
De cracker kan SQL uitvoeren in je script. Laten we maar meteen beginnen met een voorbeeld. In dit voorbeeld wordt een script uitgevoerd die alle gebruikers van een webpagina laat zien. De bezoeker kan die lijst sorteren zodat alle gebruikers namen met een A vooraan en met een Z achteraan komen te staan in die lijst en omgekeerd. Deze opzet komt veel voor op het internet.
Je kan in SQL meerdere queries uitvoeren, door iedere query met een ';' af te sluiten. Raad maar eens wat er gebeurt als ik het script als volgt aanroep:
Inderdaad, de tabel 'users' zal verwijderd worden.
Voorbeeld #2
Nog een voorbeeld, je hebt een database opgezet waarin de gebruikers van jouw site hun persoonlijke bestanden in kunnen zetten. Je slaat de bestanden op in een directory en de bestandsnaam geef je een random naam. In de database heb je de echte naam van het bestand opgeslagen en een verwijzing naar de random naam:
en het volgende script heb je draaien:
Wat zou er gebeuren als je het document als volgt aanroept?
files.php?login_id=1234567890 OR 1=1
De volgende SQL query wordt uitgevoerd:
En ja hoor, alle persoonlijke bestanden die in de database zitten worden weergegeven! Niet de bedoeling dus! SQL injection is een serieus probleem, onderschat het niet.
Oplossing
Vertrouw nooit de user input die gebruikt wordt in een query. Als je de PHP optie magic_quotes_gpc op 'false' hebt staan, gebruik dan altijd addslashes() bij variabelen die je in een query gebruikt en gebruik altijd quotes bij statements in het WHERE gedeelte van een query. Dus dit is veilig:
Gebruikt slashes in het WHERE gedeelte: WHERE artikel = 'content tussen quotes'
1. Zorg er dus altijd voor dat (in dit geval) $artikel door addslashes() wordt gehaald.
2. Zorg er altijd voor dat waar die van een user komt altijd tussen quotes staat in een query.
Valid SQL houdt ondermeer in dat je bij een numeriek SQL veld geen slashes moet gebruiken in de WHERE statement. Controleer dan ook altijd of de waarde van die numerieke veld ook numeriek is! Anders stel je je site open voor SQL injection. Dus hoe het wel moet bij numerieke velden:
Verder wil ik jullie er nog op wijzen dat ge-encrypte data uit een cookie of uit een URL variabele altijd nog geaddslashed() moeten worden. Voorbeeld van een script die vatbaar is voor SQL injection:
Je eerst indruk zal zijn dat er niks mis is met dit script, maar schijn bedriegt. De cookie wordt automatisch door addslashes() gehaald, dus daar ligt het niet aan, maar we vergeten 1 ding, de cookie is ge-base64 encoded. Dus de string 'Mtp0cm91Ynk6M2U5YzliNzcxZGZkY2QyMjlhMTk0MDE1ZmViYTQ1MWM=' wordt door addslashes() gehaald. De decoded string is niet door addslashes() gehaald en die wordt in dit script ook niet door addslashes() gehaald, foute boel dus. Hoe buit je dit lek uit? Draai dit PHP script:
Ze de uitkomst daarvan als cookie. Het script zal nu het volgende uitvoeren in haar query:
SELECT email FROM members WHERE id = '1' AND password = 'blabla'; SOME SQL; SELECT * FROM members WHERE id = '1'
Wanneer je dus encoding of encrypty gebruikt in een cookie, post of get variabele, gebruikt dan addslashes() over de decoded of decrypted waarde!
Als je de SQL injection hacks nog steeds niet erg goed snapt, dan doe je er goed aan om eens naar wat meer voorbeelden te kijken:
PHP manual SQL injection http://www.php.net/manual/en/security.database.php
PHP-Nuke hack http://www.wiretrip.net/rfp/txt/rfp2101.txt
PacketStorm hack http://www.wiretrip.net/rfp/txt/rfp2k01.txt
Noot
De functie mysql_query() staat niet toe om meerdere queries uit te voeren, hoewel SQL dat wel toestaat. De
bovenstaande voorbeelden waarbij meerdere queries worden uitgevoerd, gescheiden door een ';' zullen
daarom niet werken via de PHP functie mysql_query(). SQL ondersteunt wel meerdere queries dus daarom
heb ik ook meerdere querie hacks opgenomen in mijn voorbeelden.
Voorbeeld #1
De cracker kan SQL uitvoeren in je script. Laten we maar meteen beginnen met een voorbeeld. In dit voorbeeld wordt een script uitgevoerd die alle gebruikers van een webpagina laat zien. De bezoeker kan die lijst sorteren zodat alle gebruikers namen met een A vooraan en met een Z achteraan komen te staan in die lijst en omgekeerd. Deze opzet komt veel voor op het internet.
Code | Selecteer Alles![]() |
|---|
|
Je kan in SQL meerdere queries uitvoeren, door iedere query met een ';' af te sluiten. Raad maar eens wat er gebeurt als ik het script als volgt aanroep:
Code | Selecteer Alles![]() |
|---|
|
Inderdaad, de tabel 'users' zal verwijderd worden.
Voorbeeld #2
Nog een voorbeeld, je hebt een database opgezet waarin de gebruikers van jouw site hun persoonlijke bestanden in kunnen zetten. Je slaat de bestanden op in een directory en de bestandsnaam geef je een random naam. In de database heb je de echte naam van het bestand opgeslagen en een verwijzing naar de random naam:
Code | Selecteer Alles![]() |
|---|
|
en het volgende script heb je draaien:
Code | Selecteer Alles![]() |
|---|
|
Wat zou er gebeuren als je het document als volgt aanroept?
files.php?login_id=1234567890 OR 1=1
De volgende SQL query wordt uitgevoerd:
Code | Selecteer Alles![]() |
|---|
|
En ja hoor, alle persoonlijke bestanden die in de database zitten worden weergegeven! Niet de bedoeling dus! SQL injection is een serieus probleem, onderschat het niet.
Oplossing
Vertrouw nooit de user input die gebruikt wordt in een query. Als je de PHP optie magic_quotes_gpc op 'false' hebt staan, gebruik dan altijd addslashes() bij variabelen die je in een query gebruikt en gebruik altijd quotes bij statements in het WHERE gedeelte van een query. Dus dit is veilig:
Code | Selecteer Alles![]() |
|---|
|
Gebruikt slashes in het WHERE gedeelte: WHERE artikel = 'content tussen quotes'
1. Zorg er dus altijd voor dat (in dit geval) $artikel door addslashes() wordt gehaald.
2. Zorg er altijd voor dat waar die van een user komt altijd tussen quotes staat in een query.
Valid SQL houdt ondermeer in dat je bij een numeriek SQL veld geen slashes moet gebruiken in de WHERE statement. Controleer dan ook altijd of de waarde van die numerieke veld ook numeriek is! Anders stel je je site open voor SQL injection. Dus hoe het wel moet bij numerieke velden:
Code | Selecteer Alles![]() |
|---|
|
Verder wil ik jullie er nog op wijzen dat ge-encrypte data uit een cookie of uit een URL variabele altijd nog geaddslashed() moeten worden. Voorbeeld van een script die vatbaar is voor SQL injection:
Code | Selecteer Alles![]() |
|---|
|
Je eerst indruk zal zijn dat er niks mis is met dit script, maar schijn bedriegt. De cookie wordt automatisch door addslashes() gehaald, dus daar ligt het niet aan, maar we vergeten 1 ding, de cookie is ge-base64 encoded. Dus de string 'Mtp0cm91Ynk6M2U5YzliNzcxZGZkY2QyMjlhMTk0MDE1ZmViYTQ1MWM=' wordt door addslashes() gehaald. De decoded string is niet door addslashes() gehaald en die wordt in dit script ook niet door addslashes() gehaald, foute boel dus. Hoe buit je dit lek uit? Draai dit PHP script:
Code | Selecteer Alles![]() |
|---|
|
Ze de uitkomst daarvan als cookie. Het script zal nu het volgende uitvoeren in haar query:
SELECT email FROM members WHERE id = '1' AND password = 'blabla'; SOME SQL; SELECT * FROM members WHERE id = '1'
Wanneer je dus encoding of encrypty gebruikt in een cookie, post of get variabele, gebruikt dan addslashes() over de decoded of decrypted waarde!
Als je de SQL injection hacks nog steeds niet erg goed snapt, dan doe je er goed aan om eens naar wat meer voorbeelden te kijken:
PHP manual SQL injection http://www.php.net/manual/en/security.database.php
PHP-Nuke hack http://www.wiretrip.net/rfp/txt/rfp2101.txt
PacketStorm hack http://www.wiretrip.net/rfp/txt/rfp2k01.txt
Noot
De functie mysql_query() staat niet toe om meerdere queries uit te voeren, hoewel SQL dat wel toestaat. De
bovenstaande voorbeelden waarbij meerdere queries worden uitgevoerd, gescheiden door een ';' zullen
daarom niet werken via de PHP functie mysql_query(). SQL ondersteunt wel meerdere queries dus daarom
heb ik ook meerdere querie hacks opgenomen in mijn voorbeelden.
Er werd nog geen reactie geplaatst.

