login  Naam:   Wachtwoord: 
Registreer je!
 Forum

Query opbouw

Offline zwobbel - 30/09/2006 17:18
Avatar van zwobbelPHP gevorderde Als ik het forum zo bezoek en bekijk zie ik altij zoveel verschillende soorten opbouw van mysql query's en ik vroeg me nu af Wat de beste en meest veilige mannier is van opstelling van een query.
Ook vroeg ik me af wat nu de meest veilige controle is bij een $_post[""] & een $_get[""] ?

Zodat ze geen php injecties, html inject of andere dinges kunnen uithalen met je query.
Met andere woorden wie kan mij nu is duidelijk en krachtig zeggen wat het meest veilige en beste is!?

11 antwoorden

Gesponsorde links
Offline Dark_Paul - 30/09/2006 17:39
Avatar van Dark_Paul PHP ver gevorderde Ik zou zeggen, controleren met een regex. Dan kan je zelf bepalen wat er in voor mag komen.
Offline zwobbel - 01/10/2006 10:36 (laatste wijziging 01/10/2006 10:36)
Avatar van zwobbel PHP gevorderde Heeft nu echt niemand hier nog een beter uitleg op?? Dit verbaasd me!
Dit is namelijk best wel belangrijk zeker ook voor beginnende, zodat ze het van eerste keer goed aanleren...
Offline marten - 01/10/2006 11:02
Avatar van marten Beheerder Zelf gebruik ik altijd dynamische queries in combinatie met reflectionClass(); Deze zit standaard in PHP5.

Verder kan ik alleen maar zeggen:
http://www.site...amp;id=747
Offline ikkedikke - 01/10/2006 14:54
Avatar van ikkedikke PHP expert de veiligheid van GET en POST zijn allebei nihil,
ze komen in een request allebei ongecodeerd voor oid en zijn allebei aan te passen.
verder zou ik zo veel mogeljk met cijfers als waarden voor je variabelen werken omdat die het makkelijkst te controleren zijn met ctype_digit en dingen als
$a = (int) $a;
als laatste zou ik je aanraden om je queries logisch over meerdere regels te verdelen. je krijgt dan namelijk ook bij foutmeldingen de regel te zien, en als daar bij jou maar 1 of 2 dingen staan is het snel gevonden.
Offline bosgroen - 01/10/2006 23:31
Avatar van bosgroen Gouden medaille

PHP interesse
Citaat:
$a = (int) $a;

Zelfs dit is gevaarlijk, want indien $a een tekst is, zal $a een nul worden. Stel nu dat je ergens in je query WHERE id = $a hebt staan, tja, dan zal hij rij met id=0 pakken, wat in sommige gevallen een veiligheidsrisico kan betekenen

Ik heb een scriptje dat ik vond op het internet omgebouwd en geimplementeerd in mijn database-klasse. tgaat om SafeSQL.class by Monte Ohrt script, dat met %i en %s werkt in de query, en de vars dan apart worden doorgegeven na extra controle. Beetje zoals ook PEAR werkt. Handig en veilig, als je het wat met hersens gebruikt tenminste!
Offline xSc - 02/10/2006 09:58
Avatar van xSc Onbekend Er zijn nog meer mogelijkheden.

Binnen queries kun (moet) je deze functies gebruiken:

mysql_real_escape_string()
addslashes()
intval()
floatval()

Handig is ook array_map voor $_POST / $_GET

$_POST = array_map('addslashes', $_POST);
Offline Wijnand - 02/10/2006 10:02
Avatar van Wijnand Moderator Het probleem is dat er verschillende stylen zijn die je kunt gebruiken. En er hoeft er niet één perse "beter" te zijn. Daarom zijn mensen voorzichting (iig ik) om te zeggen: "zo en zo MOET je het doen".

En over die POST/GET.... daar zou ik een functie (recursief) voor schrijven die elke item langs gaat en de key en de value even door htmlspecialchars() haalt of iets in die richting.

En over de opbouw van de query... hoe bedoel je dat? bedoel je hoe je met tabjes in een query moet/kan werken?
Offline Thomas - 02/10/2006 11:39 (laatste wijziging 02/10/2006 11:40)
Avatar van Thomas Moderator Ik gebruik (voor form-data) een functie die waar nodig addslashes of htmlentities toevoegt. Standaard zet ik magic_quotes_gpc uit.

Ook wordt gecontroleerd of het $_POST-element bestaat.
Tevens biedt deze functie ondersteuning voor array-invoer uit forms (veldnaam[]).

Mijn database-tabellen zijn zo opgezet dat numerieke kolommen met de waarde "0" geen betekenis hebben / niet geïnitialiseerd zijn.

Als een formulier-veld numeriek zou moeten zijn, maar geen geschikte waarde heeft, dan initialiseer ik deze op 0 ("niet-geïnitialiseerd").

Bij het bouwen van de query kun je dus of volstaan met deze functie voor tekstinvoer, deze functie + is_numeric controle voor numerieke invoer - als invoer aan specifieke kenmerken moet voldoen, gebruik je ook een reguliere expressie.

Je hebt eigenlijk 3 "niveaus" van controleren (naast controles voor het tegengaan van SQL-injecties enzo):

1. Controleren of een veld "niet leeg" is
2. De waarde van een veld controleren op een bepaald type
3. Onderlinge samenhang van ingevulde waarden controleren

#1 is het makkelijkste, en met #3 wordt je formuliercontrole vrij uitgebreid. In eerste instantie moeten de formuliergegevens veilig worden verwerkt tot een kloppende query, waar eerdergenoemde functie voor dient.
Daarna(ast) verschilt het per formulier hoe je deze verwerkt... dus daarvoor is niet echt één oplossing te geven.

Functie die ik gebruik:
  1. <?php
  2. // @param $field (string) naam van formulierveld
  3. // @param $index (int) of veld indices heeft (default -1 = geen indices)
  4. // @param $preset (int) hoe de gegevens verwerkt dienen te worden (default 0 = normale form-verwerking)
  5. // @return "veilige" form-data of een lege string
  6. function form_data($field, $index=-1, $preset=0)
  7. {
  8. $ret = "";
  9.  
  10. // default - voor het verwerken van formulieren met als doel deze in database op te slaan
  11. if($preset == 0)
  12. {
  13. $add = 1;
  14. $strip = 0;
  15. $trim = 1;
  16. $safe = 0;
  17. }
  18.  
  19. // voor het verwerken van formulieren met als doel deze in direct te verwerken, bijvoorbeeld in een e-mail
  20. if($preset == 1)
  21. {
  22. $add = 0;
  23. $strip = 0; // verwijdert anders slashes uit het oorspronkelijke bericht
  24. $trim = 1;
  25. $safe = 1;
  26. }
  27.  
  28. if($index > -1)
  29. {
  30. if(isset($_POST[$field][$index]))
  31. {
  32. $ret = $_POST[$field][$index];
  33. }
  34. }
  35. else
  36. {
  37. if(isset($_POST[$field]))
  38. {
  39. $ret = $_POST[$field];
  40. }
  41. }
  42.  
  43. $ret = ($add) ? addslashes($ret) : $ret;
  44. $ret = ($strip) ? stripslashes($ret) : $ret;
  45. $ret = ($trim) ? trim($ret) : $ret;
  46. $ret = ($safe) ? htmlentities($ret) : $ret;
  47.  
  48. return $ret;
  49. }
Offline Wijnand - 02/10/2006 12:13
Avatar van Wijnand Moderator
  1. <?php
  2. function fChecker($val)
  3. {
  4. if (is_array($val)) {
  5. foreach ($val AS $k=>$v) {
  6. if (is_array($v)) {
  7. $val[$k] = fChecker($v);
  8. } else {
  9. $val[$k] = htmlspecialchars($v, ENT_QUOTES);
  10. }
  11. if ($k != htmlspecialchars($k, ENT_QUOTES)) {
  12. $temp = $val[$k];
  13. unset($val[$k]);
  14. $val[htmlspecialchars($k, ENT_QUOTES)] = $temp;
  15. }
  16. }
  17. }
  18. return $val;
  19. }
  20. ?>


Dit scriptje heb ik net geschreven. Even heel simpel, maar het maakt alle keys en values "veilig" door htmlspecialchars (ENT_QUOTES ook) er overheen uit te voeren.

Hij houd ook rekening met array-invoer vanuit formulieren.
Offline bosgroen - 02/10/2006 19:26 (laatste wijziging 02/10/2006 19:27)
Avatar van bosgroen Gouden medaille

PHP interesse
mogelijke mysql-abuse op wijnand scriptje:
(ter info, waarschijnlijk doet wijnand nog andere controles)

$pass = fChecker($_GET['pass']);
$user_id = fChecker($_GET['user_id']);

SELECT * WHERE pass = '$pass' AND id = $user_id

(Indien wijnand geen '' zet om user_id, omdat hij een integer verwacht, maar niet controleert of dit er werkelijk één is.)
wat als iemand ervoor zorgt dat $_GET['user_id'] = '5 OR NOT( id = 5 )';
Dan wordt volgen SQL uitgevoerd, desondanks de fChecker-functie. (Let erop dat ik NOT id = gebruik en niet id <> want deze laatste zal wijnands-functie tegenhouden)

SELECT * WHERE pass = '$pass' AND id = 5 OR NOT( id = 5 )
Offline Wijnand - 03/10/2006 09:40
Avatar van Wijnand Moderator Ja die single quotes erom heen zijn super logisch. Vandaar dat ik het er niet bij heb gezet. Je hebt gelijk..... had ik erbij kunnen zetten.

shame on me 
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2025 Sitemasters.be - Regels - Laadtijd: 0.21s