is deze database query veilig genoeg?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Ama saril

ama saril

13/11/2012 15:19:14
Quote Anchor link
Hoi Mensen,

Ik heb nog niet zo heel veel met beveiliging van database queries gedaan vandaar dat ik hier even mee bezig ben.

Ik heb de volgende classe:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
Class ZoekClass extends DatabaseClass{
    
    private function checkString($waarde)
    {

        $veilig = mysql_real_escape_string((get_magic_quotes_gpc())? stripslashes($waarde): $waarde);
        return $veilig;
    }

    
    public function zoekFunctie($nummer)
    {

        $con = $this->maakVerbinding();
        $query = "SELECT naam, achternaam FROM tbl_gegevens WHERE id='".$this->checkString($nummer)."'";
        //voer query uit etc....
        $this->sluitVerbinding($con);
    }
}


?>


Nu wilde ik graag weten is de functie checkString($waarde) genoeg om ervoor te zorgen dat ik geen sqlinjectie tegen me krijg (plan is om elke variabel die ik in me query gebruik door deze functie te laten lopen)? En zo niet, wat zou ik daar dan nog meer aan kunnen doen?
 
PHP hulp

PHP hulp

21/11/2024 20:22:01
 
TJVB tvb

TJVB tvb

13/11/2012 15:39:37
Quote Anchor link
Waarom maak en sluit je elke keer een verbinding?
Dat maakt het heel traag (10 query's = 10 keer verbinding maken en sluiten i.p.v. 1 keer)

Oja, het ziet er veilig uit
Gewijzigd op 13/11/2012 15:40:06 door TJVB tvb
 
Ama saril

ama saril

13/11/2012 15:43:11
Quote Anchor link
TJVB tvb op 13/11/2012 15:39:37:
Waarom maak en sluit je elke keer een verbinding?
Dat maakt het heel traag (10 query's = 10 keer verbinding maken en sluiten i.p.v. 1 keer)

Oja, het ziet er veilig uit


Ik sluit uiteraard de verbinding pas als al mijn queries zijn uitgevoerd :)
 
TJVB tvb

TJVB tvb

13/11/2012 15:44:14
Quote Anchor link
Ama saril op 13/11/2012 15:43:11:
Ik sluit uiteraard de verbinding pas als al mijn queries zijn uitgevoerd :)


Oke, want in de code die je laat zien doe je dat meteen
 
- SanThe -

- SanThe -

13/11/2012 15:49:24
Quote Anchor link
In bovenstaand zie ik nergens dat er een query wordt uitgevoerd.
Gewijzigd op 13/11/2012 15:50:20 door - SanThe -
 
Ama saril

ama saril

13/11/2012 15:55:35
Quote Anchor link
- SanThe - op 13/11/2012 15:49:24:
In bovenstaand zie ik nergens dat er een query wordt uitgevoerd.


Ook al heb je het doorgestreept ter verduidelijking; ik wilde de focus graag leggen op de sqlinjectie functie. Het uitvoeren van een query, foutafhandeling en het ophalen van variabelen heb ik geen vragen over dus heb ik dat eruitgegooid anders wordt het code voorbeeld zo lang :)
 
Kris Peeters

Kris Peeters

13/11/2012 15:57:52
Quote Anchor link
Ik heb ook al verschillende keren een wrapper class gemaakt om databases aan te pakken.

Nu, misschien is dit toch met juiste moment om eens te kijken naar PDO, en hoe die omgaat met de beveiliging van user data

zie http://www.phphulp.nl/php/tutorial/overig/pdo-verbinden-met-verschillende-databases/534/prepared-statements/1368/
Gewijzigd op 13/11/2012 16:00:49 door Kris Peeters
 
Stefan WM

Stefan WM

13/11/2012 16:14:55
Quote Anchor link
@kris, je haalt de woorden uit me mond!
 
Ama saril

ama saril

13/11/2012 16:16:41
Quote Anchor link
Kris Peeters op 13/11/2012 15:57:52:
Ik heb ook al verschillende keren een wrapper class gemaakt om databases aan te pakken.

Nu, misschien is dit toch met juiste moment om eens te kijken naar PDO, en hoe die omgaat met de beveiliging van user data

zie http://www.phphulp.nl/php/tutorial/overig/pdo-verbinden-met-verschillende-databases/534/prepared-statements/1368/


Ah bedankt had nog niet echt aan PDO gedacht. Misschien toch is tijd om de tutorial te bekijken, bedankt.

edit---
Terzijde:
Is mijn functie checkString($waarde) wel voldoende om sql injectie tegen te gaan :P?
Ook al ga ik de class dan waarschijnlijk toch ombouwen naar PDO of mysqli ben ik toch beniewd.
Gewijzigd op 13/11/2012 16:18:50 door ama saril
 
Kris Peeters

Kris Peeters

13/11/2012 16:21:22
Quote Anchor link
mysql_real_escape_string is in principe voldoende om beschermd te zijn tegen injection. Dus ja, het lijkt me wel veilig.
 
Stefan WM

Stefan WM

13/11/2012 16:48:45
Quote Anchor link
Ik zou eerder voor PDO als mysqli gaan eerlijk gezegd.
 
Ama saril

ama saril

13/11/2012 17:05:52
Quote Anchor link
Stefan van den Broek op 13/11/2012 16:48:45:
Ik zou eerder voor PDO als mysqli gaan eerlijk gezegd.


Ben op dit moment beide methoden aan het bekijken dan kan ik later beslissen welke ik ga gebruiken. Wil hoe dan ook weten hoe beide werken.
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

13/11/2012 19:27:03
Quote Anchor link
Toch nog maar eens deze opmerking.

Omdat je in zowel PDO als mysqli parameters in combinatie met een prepared statement moet gebruiken, is het uiteindelijke doel van een prepared statement geheel voorbij gestreefd. Dat doel is nl. om een x aantal dezelfde queries achter elkaar sneller te laten verlopen.
Bij mij is dat 9999 van de 10.000 gewoon 1 query, dus voorlopig blijf mijn keuze nog bij mysqli omdat ik daar tenminste nog de escape mogelijk heb.
 
Wouter J

Wouter J

09/12/2012 21:52:28
Quote Anchor link
Ger, zowel PDO als MySQLi hoefen niet via prepared statements gebruikt te worden. Het wordt alleen heel vaak gebruikt in tutorials omdat dat het grote verschil is met de mysql_* extensie.

MySQLi geeft je een mysqli.query functie om normale queries uit te voeren en geeft je een mysqli.real_escape_string functie om te escapen.

PDO geeft je een pdo.query functie die dezelfde functionaliteit heeft als MySQLi::query() en mysql_query(). Maar het geeft je ook een pdo.exec functie die hetzelfde doet, alleen met een toevoeging dat het het aantal 'affected rows' returned, waardoor je dat in 1 kan doen. Daarnaast geeft PDO je pdo.quote om variabelen te escapen.

Hierin zie je precies de rede waarom ik eerder PDO zou gebruiken dan MySQLi, PDO biedt je op bijna elk vlak extra dingen, waar MySQLi gewoon een vreemde functional to object translation is.


Overigens hoeft prepared statement helemaal niet de rede te zijn dat je PDO of MySQLi moet gebruiken. Prepared statements zijn niks anders dan wat queries die je ook zelf met de mysql_* extensie kunt uitvoeren: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html
Gewijzigd op 09/12/2012 22:00:52 door Wouter J
 
Ama saril

ama saril

09/12/2012 23:43:06
Quote Anchor link
Wouter J op 09/12/2012 21:52:28:
Ger, zowel PDO als MySQLi hoefen niet via prepared statements gebruikt te worden. Het wordt alleen heel vaak gebruikt in tutorials omdat dat het grote verschil is met de mysql_* extensie.

MySQLi geeft je een mysqli.query functie om normale queries uit te voeren en geeft je een mysqli.real_escape_string functie om te escapen.

PDO geeft je een pdo.query functie die dezelfde functionaliteit heeft als MySQLi::query() en mysql_query(). Maar het geeft je ook een pdo.exec functie die hetzelfde doet, alleen met een toevoeging dat het het aantal 'affected rows' returned, waardoor je dat in 1 kan doen. Daarnaast geeft PDO je pdo.quote om variabelen te escapen.

Hierin zie je precies de rede waarom ik eerder PDO zou gebruiken dan MySQLi, PDO biedt je op bijna elk vlak extra dingen, waar MySQLi gewoon een vreemde functional to object translation is.


Overigens hoeft prepared statement helemaal niet de rede te zijn dat je PDO of MySQLi moet gebruiken. Prepared statements zijn niks anders dan wat queries die je ook zelf met de mysql_* extensie kunt uitvoeren: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html


wat is de functie dan van pdo.quote? pdo was tochzo opgezet dat je geen variabele hoeft te escapen?
 
Erwin H

Erwin H

10/12/2012 00:02:34
Quote Anchor link
Absoluut niet. Dat heeft niets met PDO te maken. Veel mensen gebruiken PDO omdat het makkelijker is om er veilig mee te werken, maar je kan er nog net zo onveilig mee werken als met de mysql statements. Ook als je in PDO direct variabele copieert in een SQL statement ga je nog net zo hard onderuit.

De echte reden van het opzetten van PDO kan je lezen op de php pagina:
Quote:
The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP. Each database driver that implements the PDO interface can expose database-specific features as regular extension functions. Note that you cannot perform any database functions using the PDO extension by itself; you must use a database-specific PDO driver to access a database server.

PDO provides a data-access abstraction layer, which means that, regardless of which database you're using, you use the same functions to issue queries and fetch data. PDO does not provide a database abstraction; it doesn't rewrite SQL or emulate missing features. You should use a full-blown abstraction layer if you need that facility.

Het is een abstractie laag die het gebruik van verschillende databases mogelijk maakt onder dezelfde set van functies. Dus als je PDO gebruikt voor MySQL vandaag en morgen over wilt stappen naar Oracle of MSS, dan zou dat vrij simpel moeten zijn, omdat PDO het grootste deel van de verschillen al overbrugt.
 
Ama saril

ama saril

10/12/2012 10:45:47
Quote Anchor link
Ah ok, dus ik moet nog steeds mysql_real_escape_string() gaan gebruiken?
 
Kris Peeters

Kris Peeters

10/12/2012 11:13:15
Quote Anchor link
bindParam() regelt het escapen zelf. Dus als je op onderstaande manier met prepared statements werkt, moet je mysql_real_escape_string niet gebruiken.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
// dit is veilig
    $sql = "
        INSERT INTO tabel (naam)
        VALUES (:naam)
        "
;
    $stmt = $db->prepare($sql);
    $stmt->bindParam(':naam', $_POST['naam'], PDO::PARAM_STR);
?>


Een andere zaak is: je kan nog steeds gevaarlijke sql strings maken, bv.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
// dit is niet veilig
    $sql = "
        INSERT INTO tabel (naam)
        VALUES ('"
. $_POST['naam'] . "')
        "
;
?>


PDO zal op geen enkele manier injection voorkomen, bij dit laatste stuk code
 
Ama saril

ama saril

10/12/2012 11:45:41
Quote Anchor link
Dat is duidelijk, werd al bang. Had alles met bindParam() gedaan. Had het nie leuk gevonden om nog al me variabele te moeten escapen hiervoor, bedankt in ieder geval.
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

10/12/2012 11:46:55
Quote Anchor link
@Wouter,
Je hebt mijn reactie niet goed gelezen of niet goed begrepen. Ik heb gezegd dat je geen parameters kunt gebruiken zonder prepared statements.
 
Erwin H

Erwin H

10/12/2012 12:03:26
Quote Anchor link
Ama saril op 10/12/2012 10:45:47:
Ah ok, dus ik moet nog steeds mysql_real_escape_string() gaan gebruiken?

Dat moet je in elk geval niet doen. Dan gebruik je twee methodes door elkaar die in principe compleet los van elkaar staan. Als je prepared statements gebruikt dan kan je de input veilig verwerken met de parameters, gebruik je geen prepared statements dan kan je bijvoorbeeld de al eerder door Wouter genoemde PDO::quote() functie gebruiken.


Toevoeging op 10/12/2012 12:05:34:

Edit: waarbij ik nu zie dat je wellicht mijn eerdere reactie hebt gelezen alszijnde dat die quote functie niets met PDO te maken had. Dat was niet de strekking van het verhaal. PDO ensig is niet bedoeld om alle injecties altijd tegen te gaan, maar biedt wel bescherming via functies als quote().
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.