Versio

SQL Injection Guide

Beschrijving hoe iemand SQL injection gebruikt, en wat je er tegen kan doen.
Dit is een beknopte tutorial, verwacht er niet teveel van zal ik maar zeggen ;-)

Gesponsorde koppelingen

BHosted Hosting al vanaf € 1,- per maand

Controleer nu gratis jouw domeinnaam:

  

Inhoudsopgave

  1. Inleiding
  2. Is SQL Injection mogelijk?
  3. SQL Injection, Hoe krijg ik datastructuur?
  4. SQL Injection, Data bewerken
  5. Wat kan ik er tegen doen?
  6. Bronnen en extra

 

42 reacties op 'SQL Injection Guide'

PHP hulp
PHP hulp
0 seconden vanaf nu
 
Gesponsorde koppelingen
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
Misschien nog een aanvulling op de tutorial:

gebruik altijd quotes in een query voor de variabelen, voorbeeldje:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?
$sQuery
= 'SELECT * FROM tabel WHERE id = \'' . $variabele . '\'';

// EN NIET:

$sQuery = 'SELECT * FROM tabel WHERE id = ' . $variabele;
?>


Bij onderstaande query kan ik gewoon $variabele gelijk maken aan:

23;DELETE FROM tabel

En zeg maar dag dag records ;D

edit:

ooo vergeten, mooie tutorial..


7 jaar geleden
 
0 +1 -0 -1
vette tutorial ga ik direct eens gebruiken om mijn login script te testen voor sql injection
Jelmer rrrr
Jelmer rrrr
7 jaar geleden
 
0 +1 -0 -1
Quotes op plekken waar integers gebruikt worden is etisch gezien niet lekker. Daarbij zal mysql_query nooit meer dan 1 opdracht uitvoeren. Limitatie van PHP ;)
Leroy Boerefijn
Leroy Boerefijn
7 jaar geleden
 
0 +1 -0 -1
chille tut!!
volgens mij niets vergeten ;)

@martijn!, ik doe altijd dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$query
= "SELECT * FROM tabel WHERE id = '" . $variabele . "';
?>

dan hoef je namelijk niet met die backslases te werken..
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
Net ff gecontroleerd en mijn producten tabel was leeg.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
SELECT *
FROM p_products
WHERE 1 ;# Rijen: 3439
DELETE FROM p_products# Getroffen rijen: 3439


@leroy:

Kan ook idd...
Jelmer rrrr
Jelmer rrrr
7 jaar geleden
 
0 +1 -0 -1
Nooit vertrouwen wat anderen zeggen over PHP? :S
Ik dacht echt dat het beperkt was door PHP.

Ikzelf gebruik voor integers meestal het o zo gemene intval() of gewoon typecasting (int)

Misschien is het leuk om in de 'wat kan je er tegen doen' magic_quotes_rpc ook even te vermelden, en even aan te geven dat dit niet een oplossing is aangezien dat alleen maar lastig is en toch binnenkort weer uit PHP geslingerd wordt.


7 jaar geleden
 
0 +1 -0 -1
intval() zoals Jelmer zegt moet je gebruiken voor het selecteren van een id, en geen quotjes plaatsen. Want anders is het een string (volgens mij is MySQL ook een van de weinige systemen die dit slikt)
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
Ik heb hier een mooie oracle SQL leerboek en daarin staat:

"Let op het subtiele verschil tussen 123 en '123'! Het verschil tussen numerieke en alfanumerieke constanten komt met name tot uiting in hun bewerkingsmogelijkheden. Numerieke constanten kunnen bijvoorbeeld worden opgeteld, of met elkaar vermenigvuldigd. Met alfanumerieke constanten gaat dat niet; die kun je bijvoorbeeld aan elkaar plakken"

Maar dat is ook al weer een oude boek over Oracle7 en 8i
Klaasjan Boven
Klaasjan Boven
7 jaar geleden
 
0 +1 -0 -1
Quote:
Martijn! schreef op 01.11.2006 22:12
Ik heb hier een mooie oracle SQL leerboek en daarin staat:

"Let op het subtiele verschil tussen 123 en '123'! Het verschil tussen numerieke en alfanumerieke constanten komt met name tot uiting in hun bewerkingsmogelijkheden. Numerieke constanten kunnen bijvoorbeeld worden opgeteld, of met elkaar vermenigvuldigd. Met alfanumerieke constanten gaat dat niet; die kun je bijvoorbeeld aan elkaar plakken"


Maar dat is ook al weer een oude boek over Oracle7 en 8i

Gewijzigd op 01.11.2006 22:12 door Martijn!

Maar jij hebt het over _O_ Oracle dat is wel wat anders dan mysql. Mysql is niet zo nauwkeurig als het op wel of geen ' ' aankomt
Robert Deiman
Robert Deiman
7 jaar geleden
 
0 +1 -0 -1
Dat klopt wel Klaasjan, maar dat betekend niet dat je het niet beter op die manier kan doen. De manier van Martijn! waarbij hij zegt dat 123 en '123' anders zijn klopt, MySQL slikt dit, maar als je nu naar een ander type database overstapt?
Precies, dan kan je je beter aan de standaard hebben gehouden, dat scheelt aanpassingen. Daar komt bij dat je je sowiezo beter aan de gestelde standaard kan houden, om fouten te voorkomen.

== Mooie tut hoor ==
Legolas
Legolas
7 jaar geleden
 
0 +1 -0 -1
Eigenlijk zouden PHP en MySQL wat strikter mogen, komt het programmeerniveau ten goede
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
Je zou ook van te voren kunnen checken of een variabele in de querie een getal is. Dan hoef je de query niet meer uit te voeren, als dit niet zo is. Maar ik vind eigelijk niet dat single-quotes om numerieke waardes in queries verkeerd zijn, ik zie het meer als extra zekerheid voor als je waarde check faalt. En schijnbaar kan Oracle ook hiermee omgaan.

@Legolas:
MySQL heeft een strict modes, maar of dat wat help.

PHP mag wat mij betreft een optie in de parser maken die een error geeft als je bagger code hebt gemaakt. Hopen dat PHP6 alle bagger oplossingen aanpakt .
Willem Jan Z
Willem Jan Z
7 jaar geleden
 
0 +1 -0 -1
Quote:
Nooit vertrouwen wat anderen zeggen over PHP? :S
Ik dacht echt dat het beperkt was door PHP.

Waar ben je dan achter gekomen? Ik dacht namelijk ook dat het door PHP kwam dat je maar 1 query er in kan stoppen. Of is het een instelling oid. Want ik kan echt maar 1 query per keer uitvoeren.
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
@Willen-Jan:

SELECT * FROM p_products WHERE 1 ;DELETE FROM p_products

Ga je gang ;D
Bas Kreleger
Bas Kreleger
7 jaar geleden
 
0 +1 -0 -1
Ligt aan je MySQL instellingen of je meerdere queries in ??n keer kunt executen. PHP checked dit niet, tenzij je dit zelf inbouwt :).
Hipska BE
Hipska BE
7 jaar geleden
 
0 +1 -0 -1
php voert met mysql_query() alles na de ; toch niet meer uit?

(heb het gistere toevallig nog geprobeerd)
Niek s
niek s
7 jaar geleden
 
0 +1 -0 -1
Hipska schreef op 02.11.2006 10:30
php voert met mysql_query() alles na de ; toch niet meer uit?

(heb het gistere toevallig nog geprobeerd)

nee klopt, maar in een string wel... want anders zou je geen ; in een bericht kunnen zetten bijvoorbeeld.

mysql_query("SELECT * FROM poep; TRUNCATE TABLE henk"); werkt gewoon hoor...


(edit: typos onder voorbehoud :p)
Jelmer rrrr
Jelmer rrrr
7 jaar geleden
 
0 +1 -0 -1
Bedoel je met dat hij werkt dat hij de tabel 'henk' op de koop houdt, of dat hij gewoon die 2e opdracht negeert?
Marien xD
Marien xD
7 jaar geleden
 
0 +1 -0 -1
Vergeet de dubbele steepjes niet achter de query als je een injection doet. Dit zorgt ervoor dat de rest van de achterliggende query als commentaar gezien word:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?
mysql_query("SELECT * FROM poep; TRUNCATE TABLE henk-- WHERE blaat");
?>
Niek s
niek s
7 jaar geleden
 
0 +1 -0 -1
@Marien:

Staat ook in mijn tutorial ;-)
Leroy Boerefijn
Leroy Boerefijn
7 jaar geleden
 
0 +1 -0 -1
maar wat moet je nou gebruiken??
123 of '123' ??
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Niek s
niek s
7 jaar geleden
 
0 +1 -0 -1
voor integers moet je geen quotes gebruiken volgens mij, maar ik ben geen super expert op dat gebied.
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
@leroy

Als je het heel strikt bekijkt moet je 123 gebruiken en geen '123' alleen maakt het volgens mij niets uit. Wil je iets bij dat getal optellen bijvoorbeeld dan kun je niet '123' gebruiken.
Maar de discussie gaat erover dat die 123 dus een variabele is. Als je dan geen
single-quotes (') gebruikt dan kun je makkelijk twee queries van die enkele query maken wat dus niet de bedoeling is.
Arend a
Arend a
7 jaar geleden
 
0 +1 -0 -1
Ik vond vooral je PDFje interessant, misschien is het aardig om die ook integraal op te nemen in je tutorial?
 
0 +1 -0 -1
Voor id's moet je sowieso gewoon ctype_digit gebruiken.

Mooie tutorial!
The Hosh
The Hosh
7 jaar geleden
 
0 +1 -0 -1
een klein vraagje, is het makkelijk als niemand de tabellen weet? zullen ze makkelijk injecties gebruiken?
Niek s
niek s
7 jaar geleden
 
0 +1 -0 -1
als niemand de tabellen weet is natuurlijk perfect, maar iemand kan na een paar pogingen atlijd je tabel goed hebben gegokt.. veiliger is om het gewoon niet mogelijk te maken ;-)

Arend schreef op 02.11.2006 20:18
Ik vond vooral je PDFje interessant, misschien is het aardig om die ook integraal op te nemen in je tutorial?

Ik weet niet wat je hier mee precies bedoelt (kan aan mijn dyslexie liggen) maar kan je je zlef nog verklaren of niet?
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
@Niek:

http://www.gkvwijnjewoude.nl/schoolhack3.pdf

@Andries Louw W.:

Bij id,s doe ik dat inderdaad ook altijd in combinatie met empty.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?
$id
= 3432423;

if( !empty($id) && ctype_digit((string)$id) )
{

  # $id is een getal van 1 t/m heel veel.
}
?>
Niek s
niek s
7 jaar geleden
 
0 +1 -0 -1
Ja dat is mijn pdf, maar wat moet ik daar mee doen? ook in de tutorial zetten ofzo? ik snap het niet helemaal
Frank -
Frank -
7 jaar geleden
 
0 +1 -0 -1
Wanneer je in PostgreSQL met PL/pgSQL aan de slag gaat, daarmee gaat programeren en vervolgens iedereen de toegang tot de tabelen ontzegt, kun je SQL-injection helemaal voorkomen. Er is geen mens die de database in kan, men kan alleen van de API's gebruik maken die jij hebt geprogrameerd. En voor alle API's geldt dat jij bepaalt hoe de input en output er uit zal zien. Alles wat daar van afwijkt, laat je door de API afkeuren. Dit is vele malen veiliger dan dat met MySQL-mogelijk is, die kent dit soort oplossingen helemaal niet. Oracle heeft soortgelijke oplossingen als PostgreSQL, PL/SQL.
Martijn B
Martijn B
7 jaar geleden
 
0 +1 -0 -1
Over wat voor oplossingen heb je het nu Frank...

stored-procedures?
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Peter Wessels
Peter Wessels
7 jaar geleden
 
0 +1 -0 -1
ik krijg steeds je hebt een verkeert username ingevult bij alle systemen
Frank -
Frank -
7 jaar geleden
 
0 +1 -0 -1
@Martijn: Ik heb het over server programming en dan met name over PL/pgSQL. Zie http://www.postgresql.org/docs/8.1/interactive/server-programming.html en http://www.postgresql.org/docs/8.1/interactive/plpgsql.html

Ik ben niet goed bekend met de stored procedures van MySQL (vanaf versie 5), maar wellicht kun je daar soortgelijke resultaten mee bereiken. Alleen jammer dat MySQL al wel met de volgende waarschuwing komt: "Use of stored routines can cause replication problems.". Dat zijn problemen die je koste wat het kost probeert te vermijden!
Niek s
niek s
7 jaar geleden
 
0 +1 -0 -1
Quote:
Peter schreef op 03.11.2006 18:22
ik krijg steeds je hebt een verkeert username ingevult bij alle systemen


Dat betekent dat er geen SQL Injection mogelijk is.
Arian Stolwijk
Arian Stolwijk
7 jaar geleden
 
0 +1 -0 -1
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
function quote_smart($value){
   // Stripslashes
   if (get_magic_quotes_gpc()){
       $value = stripslashes($value);
   }

   // Quote if not a number or a numeric string
   if (!is_numeric($value)){
       $value = mysql_real_escape_string($value);
   }

   return $value;
}

?>


Dit is ook een handige functie voordat je strings in de sql query zet, om ze te beveiligen tegen SQL injection.

Zo komen ze altijd goed in de database, en hoef je ook geen stripslahes te gebruiken.

Stripslashes hoef je namelijk alleen te gebruiken als magic_quotes_gpc aan staat. Als magic_quotes_gpc aan staat en je doet dan nog eens mysql_real_escape_string() of addslashes() eroverheen wordt hij 2 keer ge slashed. (\\')
Niek s
niek s
7 jaar geleden
 
0 +1 -0 -1
die laatste check hoeft er tog niet in? want als het een getal is wort ie tog automatisch niet geslashed.. dus gewoon zo tog?:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
function dinges($value) {
    if(get_magic_quotes_gpc()) {
        $value = strip_slashes($value);
    }

    return mysql_real_escape_string($value);
}

?>
Jelle -
Jelle -
7 jaar geleden
 
0 +1 -0 -1
jah maar waarom zou je die functie uitvoeren als het nodig is. daarom heeft hij daarop gecheckt.
Legolas
Legolas
7 jaar geleden
 
0 +1 -0 -1
Te veel complexiteit waar het niet nodig is is vaak een grote veroorzaker van allerlei bugs. Dit is dan in dit geval een beetje overdreven, maar toch, denk er over na :P
Katjan
katjan
7 jaar geleden
 
0 +1 -0 -1
ach mensen, sql injection is oud.. de tijd dat dat nog kon is eigenlijk allang voorbij.. (jammer genoeg..;))
er zijn nog een paar systemen waar het wel kan.. (lerarensysteem van ict opleiding in zwolle, niet windesheim maar die andere)
maar bij de meeste systemen lukt het echt niet meer:(
Frank -
Frank -
7 jaar geleden
 
0 +1 -0 -1
@Huib: Wat probeer je hier mee te zeggen? Dat men er dus geen aandacht meer aan hoeft te besteden? Het is juist voor beginners, minstens 80% van de bezoekers van www.phphulp.nl , belangrijk dat hier tijd aan wordt besteed zodat zij ook veilige websites kunnen bouwen.
Frank -
Frank -
6 jaar geleden
 
0 +1 -0 -1
Nog een kleine aanvulling:
Gebruik PDO in PHP versie 5, SQL-injection wordt dan onmogelijk.
ToySoldier ZegIkNiet
ToySoldier ZegIkNiet
4 jaar geleden
 
0 +1 -0 -1
@ pagina "SQL Injection, Hoe krijg ik datastructuur?",

Ik ben het daar niet mee eens. Als ik als PHP'er de mysql_num_rows verberg en ik geef de PHP error, of de tabel bestaat of niet, dan kom je helemaal nergens achter..

Om te reageren heb je een account nodig en je moet ingelogd zijn.

  • Details
  • Niek s
    Door:
    Niek s
  • 7 jaar geleden
  • 10.074 x bekeken
  • Labels
  • Geen tags toegevoegd.