Maak SQL veilig
Door Yorick17 , 19 jaar geleden, 6.729x bekeken
beveiligd scripts tegen sql injection en zet vreemde caracters om naar niets, gebruikt magic quotes
Gesponsorde koppelingen
PHP script bestanden
Er zijn 23 reacties op 'Maak sql veilig'
Gesponsorde koppelingen
Leuk. Misschien handig om een controle in te bouwen wat het type is. Zoals int kan gecontroleerd worden.
En nu nog 1tje voor MySQLi :)
Ook kun je gebruik maken van NULL * i.p.v. "NULL"
* = Lees NULL en niet "NULL", net zoals true en false (boolean)
Ook zijn je haakjes overbodig in je verkorte if-statement. Ik zelf vind onnodige tekens erg irritant. Maar zo wordt wel duidelijk wat de voorwaarde is, wat je zelf fijn vindt.
En nu nog 1tje voor MySQLi :)
Ook kun je gebruik maken van NULL * i.p.v. "NULL"
* = Lees NULL en niet "NULL", net zoals true en false (boolean)
Ook zijn je haakjes overbodig in je verkorte if-statement. Ik zelf vind onnodige tekens erg irritant. Maar zo wordt wel duidelijk wat de voorwaarde is, wat je zelf fijn vindt.
$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);
Dit klopt dus niet... Zie dit:
Dit klopt dus niet... Zie dit:
PHP.net:
mysql_escape_string
Version Description
5.3.0 This function now throws an E_DEPRECATED notice.
4.3.0 This function became deprecated, do not use this function. Instead, use mysql_real_escape_string().
Version Description
5.3.0 This function now throws an E_DEPRECATED notice.
4.3.0 This function became deprecated, do not use this function. Instead, use mysql_real_escape_string().
mysql_escape_string
mysql_real_escape_string
Kan me vergissen, maar volgens mij gebruik jij die eerste ook in dit script, zie de regel die ik heb geplaatst?
mysql_real_escape_string
Kan me vergissen, maar volgens mij gebruik jij die eerste ook in dit script, zie de regel die ik heb geplaatst?
Altijd mysql_real_escape_string() eroverheen et voila. Je bent er al.
Wanneer een getal namelijk niet goed ingevuld is wil ik de bezoeker namelijk een melding teruggeven dat de waarde niet goed is en de bezoeker verzoeken een goede waarde in te vullen. Ik wil niet zomaar NULL in mijn database gooien.
Wanneer een getal namelijk niet goed ingevuld is wil ik de bezoeker namelijk een melding teruggeven dat de waarde niet goed is en de bezoeker verzoeken een goede waarde in te vullen. Ik wil niet zomaar NULL in mijn database gooien.
Ik gebruik dit altijd:
Bronnetje door Dave: http://www.phphulp.nl/php/tutorials/3/244/454/
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
function quote_smart ($value) {
if (get_magic_quotes_gpc ()) {
$value = stripslashes($value);
}
if (version_compare (phpversion (),"4.3.0") == "-1") {
return mysql_escape_string ($value);
}
else {
return mysql_real_escape_string ($value);
}
}
?>
function quote_smart ($value) {
if (get_magic_quotes_gpc ()) {
$value = stripslashes($value);
}
if (version_compare (phpversion (),"4.3.0") == "-1") {
return mysql_escape_string ($value);
}
else {
return mysql_real_escape_string ($value);
}
}
?>
Bronnetje door Dave: http://www.phphulp.nl/php/tutorials/3/244/454/
@Koen
Kun je niet beter op de functienaam controleren i.p.v. versienummer.
Kun je niet beter op de functienaam controleren i.p.v. versienummer.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
if(function_exists('mysql_real_escape_string'))
{
return mysql_real_escape_string($value);
}
else
{
return mysql_escape_string($value);
}
?>
if(function_exists('mysql_real_escape_string'))
{
return mysql_real_escape_string($value);
}
else
{
return mysql_escape_string($value);
}
?>
Weer een redelijk onzinnig script volgens mij.
quotes en escapen van input.
Heel simpel, altijd doen!
Een integer hoef je inderdaad niet te escapen, maar dan moet je 'm wel goed valideren. Valideren of er achterkomen wat er precies in een $var zit duurt vaak langer dan het gewoon maar quoten en escapen.
Baat het niet dan schaad het niet. Zo simpel is het.
Magic quotes strippen is meer verbonden aan GPC waardes IMO.
Dat je die in een query stop is een tweede.
lees ook eens: http://wiki.phpfreakz.nl/MagicQuotes
mysql_escape_string(); Als je nog op php4 draait mag ik na al deze tijd toch wel hopen dat je tenminste 4.4.8 draait. Scheelt weer een function call / check
Verder is het zeer raadzaam de 2e param van mysql_real_escape_string(); te gebruiken. Deze functie heeft namelijk een connection resource nodig. En zal als hij er zelf geen kan lokaliseren een nieuwe maken.
Dit is nodig voor de encoding. Is een kleine moeite en kan je een hoop zoeken schelen!
Leesvoer over escapen en quoten: http://www.phpfreakz.nl/forum.php?forum=2&iid=1190501
quotes en escapen van input.
Heel simpel, altijd doen!
Code (php)
1
2
3
4
2
3
4
<?php
$id = 1;
$sql = "SELECT * FROM table WHERE id = '".mysql_real_escape_string($id, $connection)."'";
?>
$id = 1;
$sql = "SELECT * FROM table WHERE id = '".mysql_real_escape_string($id, $connection)."'";
?>
Een integer hoef je inderdaad niet te escapen, maar dan moet je 'm wel goed valideren. Valideren of er achterkomen wat er precies in een $var zit duurt vaak langer dan het gewoon maar quoten en escapen.
Baat het niet dan schaad het niet. Zo simpel is het.
Magic quotes strippen is meer verbonden aan GPC waardes IMO.
Dat je die in een query stop is een tweede.
lees ook eens: http://wiki.phpfreakz.nl/MagicQuotes
mysql_escape_string(); Als je nog op php4 draait mag ik na al deze tijd toch wel hopen dat je tenminste 4.4.8 draait. Scheelt weer een function call / check
Verder is het zeer raadzaam de 2e param van mysql_real_escape_string(); te gebruiken. Deze functie heeft namelijk een connection resource nodig. En zal als hij er zelf geen kan lokaliseren een nieuwe maken.
Dit is nodig voor de encoding. Is een kleine moeite en kan je een hoop zoeken schelen!
Leesvoer over escapen en quoten: http://www.phpfreakz.nl/forum.php?forum=2&iid=1190501
PDO en Mysqli doen dit automatisch met prepared statements. Dit is snel, makkelijk en veilig, en joren heeft er een goede tutorial over geschreven:
http://www.phphulp.nl/php/tutorials/8/534/
en
http://www.lulu.com/content/4340838
http://www.phphulp.nl/php/tutorials/8/534/
en
http://www.lulu.com/content/4340838
PDO ben ik persoonlijk helemaal geen voorstander van!
Databases zijn niet gelijk dus kan je ze ook niet over 1 kam scheren!
Maar goed deze discussie gaat niet over PDO volgens mij.
En al helemaal niet over Database abstractie en nog minder over Prepared Statements.
Stop reading if you disagree...
Prepared statements gebruiken doorgaans wel variabele types.
En casten default naar strings. Alleen dan intern en net iets anders en beter.
Maar het basis idee blijft dan volgens mij hetzelfde... quote en escape alles.
Dan kan je op dat punt iig geen fouten meer maken.
Prepared statements zijn ervoor om ze te herbruiken. Als je dat niet doet zullen ze database gewijs langer memory opnemen. Als je ze niet herbruikt zijn ze dan zeker niet efficienter. Ligt ook een beetje aan de hoeveelheden.
Wellicht een beetje micro optimalisatie.
EDIT mysql ondersteunt overigens ook gewoon prepared statements hoor.
En dan hebben we het natuurlijk over de brakste database die er is technisch...
Databases zijn niet gelijk dus kan je ze ook niet over 1 kam scheren!
Maar goed deze discussie gaat niet over PDO volgens mij.
En al helemaal niet over Database abstractie en nog minder over Prepared Statements.
Stop reading if you disagree...
Prepared statements gebruiken doorgaans wel variabele types.
En casten default naar strings. Alleen dan intern en net iets anders en beter.
Maar het basis idee blijft dan volgens mij hetzelfde... quote en escape alles.
Dan kan je op dat punt iig geen fouten meer maken.
Prepared statements zijn ervoor om ze te herbruiken. Als je dat niet doet zullen ze database gewijs langer memory opnemen. Als je ze niet herbruikt zijn ze dan zeker niet efficienter. Ligt ook een beetje aan de hoeveelheden.
Wellicht een beetje micro optimalisatie.
EDIT mysql ondersteunt overigens ook gewoon prepared statements hoor.
En dan hebben we het natuurlijk over de brakste database die er is technisch...
Beste Lode, ik snap je tegenstand ten opzichte van pdo niet helemaal, en ten opzichte van prepared statements al helemaal niet, ik zeg niet dat het de enige manier is, er zijn altijd meerdere oplossingen voor het zelfde probleem.
Het enige wat ik zeg is dat wat dit script oplost al standaard opgelost is bij het gebruik van prepared statements. Niet meer en niet minder. Leek me een interessante aanvulling voor diegene die overweegt hoe je dit probleem kan oplossen.
Overigens, voor diegene die ook voor de toekomst nog willen programmeren, de lijken uit het verleden van php (het hele gedonder met magic quotes):
In php6 gaan de magic quotes eruit.
Het enige wat ik zeg is dat wat dit script oplost al standaard opgelost is bij het gebruik van prepared statements. Niet meer en niet minder. Leek me een interessante aanvulling voor diegene die overweegt hoe je dit probleem kan oplossen.
Overigens, voor diegene die ook voor de toekomst nog willen programmeren, de lijken uit het verleden van php (het hele gedonder met magic quotes):
In php6 gaan de magic quotes eruit.
Quote:
Met PDO scheer je ze juist niet over één kam vanwege de adapters. Ga eens lezen over het Adapter design pattern, want ik mis argumentatie. Bedenk ook dat er een reden is dat iedereen in heel PHP, Java, etc, etc, gebruik maakt van PDO-achtige dingen.PDO ben ik persoonlijk helemaal geen voorstander van!
Databases zijn niet gelijk dus kan je ze ook niet over 1 kam scheren!
Databases zijn niet gelijk dus kan je ze ook niet over 1 kam scheren!
Quote:
Laat dat beetje maar weg. Je mag beveiliging een hogere prioriteit geven dan 1 pico-procent snelheidswinst. Het versnellen van query's doe je met caching, niet met het niet-gebruiken van prepared statements.Wellicht een beetje micro optimalisatie.
Quote:
Absoluut niet mee eens, het hangt er vanaf hoe je het gebruikt. Als je zo beredeneert kun je makkelijk PHP de slechtste programmeertaal die er is noemen. Je praat pgFrank iets te veel na, al geeft hij argumenten in de trant van (SQL) standaarden en databasemogelijkheden. Jouw statement is volledig zinloos. Het is niet voor niets dat multinationals ook heel vaak MySQL gebruiken terwijl daar gewoon afgestudeerde IT'ers en DBA's werken.En dan hebben we het natuurlijk over de brakste database die er is technisch...
Beetje nadenken voordat je dingen roept.
Quote:
Met PDO scheer je ze juist niet over één kam vanwege de adapters. Ga eens lezen over het Adapter design pattern, want ik mis argumentatie. Bedenk ook dat er een reden is dat iedereen in heel PHP, Java, etc, etc, gebruik maakt van PDO-achtige dingen.
Jawel, want je zult alsnog veel queries moeten aanpassen als je een andere backend gaat gebruiken. En gezien dat vaak niet gebeurt, is het veel efficienter om er iets lightweights achter te hangen, in plaats van de hele overhead van PDO.
Quote:
Laat dat beetje maar weg. Je mag beveiliging een hogere prioriteit geven dan 1 pico-procent snelheidswinst. Het versnellen van query's doe je met caching, niet met het niet-gebruiken van prepared statements.
Zoals Lode al zei, prepared statements zijn eigenlijk alleen nuttig als het een query is die je vaker met verschillende parameters gaan aanroepen. Anders is het gewoon overkill, door het geheugengebruik. Een simpele query met sprintf en een escapemethode over de parameters heen is toch iets sneller, en net zo veilig.
Quote:
Absoluut niet mee eens, het hangt er vanaf hoe je het gebruikt.
Nouja, ik verlies geregeld data op m'n werk, en daar gebruiken we MySQL. Op een ander systeem waar ik aan werk gebruik ik Postgres, die verder compleet niet is geconfigureerd. Enkele keren gecrashed, maar nooit dataverlies geleden, terwijl dat onder MySQL zelfs gebeurde toen het niet crashte.
Quote:
Het is niet voor niets dat multinationals ook heel vaak MySQL gebruiken terwijl daar gewoon afgestudeerde IT'ers en DBA's werken.
Geweldige ad verecundiam, dat zij dat doet wil niet zeggen dat ze alles weten.
Beetje nadenken voordat je dingen roept.
Quote:
Jawel, want je zult alsnog veel queries moeten aanpassen als je een andere backend gaat gebruiken. En gezien dat vaak niet gebeurt, is het veel efficienter om er iets lightweights achter te hangen, in plaats van de hele overhead van PDO.
Quote:
Met PDO scheer je ze juist niet over één kam vanwege de adapters. Ga eens lezen over het Adapter design pattern, want ik mis argumentatie. Bedenk ook dat er een reden is dat iedereen in heel PHP, Java, etc, etc, gebruik maakt van PDO-achtige dingen.
Jawel, want je zult alsnog veel queries moeten aanpassen als je een andere backend gaat gebruiken. En gezien dat vaak niet gebeurt, is het veel efficienter om er iets lightweights achter te hangen, in plaats van de hele overhead van PDO.
PDO is niet bedoeld om gemakkelijk van back-end te kunnen veranderen, dat is gewoon een bijkomende optie die je (inderdaad) eigenlijk niet zult (kunnen) gebruiken.
Waarom dan wel PDO? PDO is gewoon een database classe met daarin alle voordelen van een classe. Een kort voorbeeldje:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
$pagina = new pagina;
$error = new error;
try
{
$db = new PDO('mysql:host=localhost;dbname=x', 'x', 'x');
$db->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
$error->addError(1, $e->getFile(), $e->getLine(), $e->getMessage());
if(DEBUG == 1)
{
$pagina->setContent = $error->showLastError();
}
}
if($error->getErrors(1) < 1)
{
try
{
$sql = "SELECT
id,
naam
FROM
paginas";
$pagina->addContent('<h1>Bewerk pagina\'s</h1>
<p>
<form method="post" action="pagina.php">
<select name="pagina">
<option value="0">Selecteer een pagina</option>');
foreach($db->query($sql) as $result)
{
$pagina->addContent('<option value="'.$result['id'].'">'.htmlentities($result['naam']).'</option>');
}
$pagina->addContent(' </select>
</form>
</p>');
}
catch (PDOException $e)
{
$pagina->addContent('Het formulier kan niet getoond worden');
$error->addError(2, $e->getFile(), $e->getLine(), $e->getMessage());
if(DEBUG == 1)
{
$pagina->addContent($error->getLastError());
}
}
}
?>
$pagina = new pagina;
$error = new error;
try
{
$db = new PDO('mysql:host=localhost;dbname=x', 'x', 'x');
$db->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
$error->addError(1, $e->getFile(), $e->getLine(), $e->getMessage());
if(DEBUG == 1)
{
$pagina->setContent = $error->showLastError();
}
}
if($error->getErrors(1) < 1)
{
try
{
$sql = "SELECT
id,
naam
FROM
paginas";
$pagina->addContent('<h1>Bewerk pagina\'s</h1>
<p>
<form method="post" action="pagina.php">
<select name="pagina">
<option value="0">Selecteer een pagina</option>');
foreach($db->query($sql) as $result)
{
$pagina->addContent('<option value="'.$result['id'].'">'.htmlentities($result['naam']).'</option>');
}
$pagina->addContent(' </select>
</form>
</p>');
}
catch (PDOException $e)
{
$pagina->addContent('Het formulier kan niet getoond worden');
$error->addError(2, $e->getFile(), $e->getLine(), $e->getMessage());
if(DEBUG == 1)
{
$pagina->addContent($error->getLastError());
}
}
}
?>
Ik hoef niet te checken of de query wel gelukt is of niet, ik krijg geen formulier met een lege <select> omdat de query mislukt is.
Wanneer ik meerdere Query's uit wil voeren start ik gewoon een transaction uitvoeren met een rollback() in de Catch. Ik hoef dus niet iedere query opnieuw te controleren en in iedere controle bij en fout een rollback uit te voeren.
Dat is de kracht achter PDO. Niet het snel kunnen verwisselen van databse, want dat gebruik je toch niet.
Ik heb mijn eigen database classes geschreven voor mijn framework.
Tenminste diegene die ik op nodig heb of had. stuk of 4 DBA's.
Maar goed dat kan wellicht al niet eens iedereen laat staan dat ze er tijd voor hebben. Maar het kan je een hoop geneuzel met die drivers schelen al bijvoorbeeld en het kan nog veel uitgebreider als PDO bijvoorbeeld...
Tenminste diegene die ik op nodig heb of had. stuk of 4 DBA's.
Maar goed dat kan wellicht al niet eens iedereen laat staan dat ze er tijd voor hebben. Maar het kan je een hoop geneuzel met die drivers schelen al bijvoorbeeld en het kan nog veel uitgebreider als PDO bijvoorbeeld...
Om te reageren heb je een account nodig en je moet ingelogd zijn.
Inhoudsopgave
Labels
- Geen tags toegevoegd.
PHP hulp
0 seconden vanaf nu