Ben ik beschermd tegen SQL injection?
Ik ben nu een 2-tal weken bezig met php & mysql. Ik werk aan de hand van een boek die pas uitgekomen is en van de recentste Lynda.com videos. Ik focus me op Mysqli ipv PDO omdat ik zelf toch uitsluitend werk met Mysql. Het bevalt me enorm! Het enige dat er natuurlijk gebeurd is dat je na een tijdje begint te experimenteren. Het werkt en je bent blij...maar is het wel goed?...of correct?
Ik heb bijvoorbeeld iets simpels in elkaar geflanst, vlug vlug...
Doordat men enorm waarschuwt voor sql injection werk ik met prepared statements....
Kan iemand mij vertellen of mijn spaghetticode op "iets" trekt en veilig is? Ben ik op de goede weg?
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<form action="homes.php" method="POST">
<p>Zoek: <input type="text" name="search" /></p>
<p>Voornaam: <input type="text" name="Voornaam" /></p>
<p>Achternaam: <input type="text" name="Achternaam" /></p>
<p>Adres: <input type="text" name="Adres" /></p>
<p>Discipline: <input type="text" name="Discipline" value="1 tot 5" /></p>
<p>Bevestig zoeken: <input type="submit" name="Submit" /></p>
<p>Voeg toe aan databank <input type="submit" name="Add_DB" value="Add to Database" /></p>
</form>
<?php
require_once 'isset.php';
?>
</body>
</html>
This is the PHP
<?php
require_once 'login.php';
$dbcon = mysqli_connect($db_host, $db_username, $db_password, $db_database);
if(mysqli_connect_errno()) die ("Error during connection");
if(isset($_POST['Submit'])){
$Naam = $_POST['search'];
$Result = mysqli_query($dbcon,"SELECT * FROM customers WHERE Voornaam = '$Naam'");
if(!$Result) die ("Nothing to show");
$Rows = $Result->num_rows;
for($i=0; $i < $Rows; $i++){
$Row = mysqli_fetch_array($Result, MYSQLI_ASSOC);
echo "Voornaam: " . $Row['Voornaam'] . "<br>";
echo "Achternaam: " . $Row['Achternaam'] . "<br>";
echo "Adres: " . $Row['Adres'] . "<br>";
echo "<hr>";
}
}
if(isset($_POST['Add_DB'])){
$sql="INSERT INTO customers(Voornaam, Achternaam, Adres, Actief, Discipline)
VALUES(?,?,?,NOW(),?)";
if($stmt = $dbcon->prepare($sql)){
$stmt->bind_param('sssi', $Voornaam, $Achternaam, $Adres, $Discipline);
$Voornaam = $_POST['Voornaam'];
$Achternaam = $_POST['Voornaam'];
$Adres = $_POST['Adres'];
$Discipline = $_POST['Discipline'];
$stmt->execute();
echo "New records created successfully";
}
}
mysqli_close($dbcon);
?>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<form action="homes.php" method="POST">
<p>Zoek: <input type="text" name="search" /></p>
<p>Voornaam: <input type="text" name="Voornaam" /></p>
<p>Achternaam: <input type="text" name="Achternaam" /></p>
<p>Adres: <input type="text" name="Adres" /></p>
<p>Discipline: <input type="text" name="Discipline" value="1 tot 5" /></p>
<p>Bevestig zoeken: <input type="submit" name="Submit" /></p>
<p>Voeg toe aan databank <input type="submit" name="Add_DB" value="Add to Database" /></p>
</form>
<?php
require_once 'isset.php';
?>
</body>
</html>
This is the PHP
<?php
require_once 'login.php';
$dbcon = mysqli_connect($db_host, $db_username, $db_password, $db_database);
if(mysqli_connect_errno()) die ("Error during connection");
if(isset($_POST['Submit'])){
$Naam = $_POST['search'];
$Result = mysqli_query($dbcon,"SELECT * FROM customers WHERE Voornaam = '$Naam'");
if(!$Result) die ("Nothing to show");
$Rows = $Result->num_rows;
for($i=0; $i < $Rows; $i++){
$Row = mysqli_fetch_array($Result, MYSQLI_ASSOC);
echo "Voornaam: " . $Row['Voornaam'] . "<br>";
echo "Achternaam: " . $Row['Achternaam'] . "<br>";
echo "Adres: " . $Row['Adres'] . "<br>";
echo "<hr>";
}
}
if(isset($_POST['Add_DB'])){
$sql="INSERT INTO customers(Voornaam, Achternaam, Adres, Actief, Discipline)
VALUES(?,?,?,NOW(),?)";
if($stmt = $dbcon->prepare($sql)){
$stmt->bind_param('sssi', $Voornaam, $Achternaam, $Adres, $Discipline);
$Voornaam = $_POST['Voornaam'];
$Achternaam = $_POST['Voornaam'];
$Adres = $_POST['Adres'];
$Discipline = $_POST['Discipline'];
$stmt->execute();
echo "New records created successfully";
}
}
mysqli_close($dbcon);
?>
Groeten,
Michaël
- Aar -:
Gelieve in het vervolg bij code de [code][/code]-tags gebruiken.
Hier kan je meer lezen over de mogelijke opmaakcodes.
Alvast bedankt!
Hier kan je meer lezen over de mogelijke opmaakcodes.
Alvast bedankt!
Gewijzigd op 15/12/2014 22:20:31 door - Ariën -
De POST waardes moet je als je ze in je query gebruik door mysqli_real_escape halen dat doe je nu niet bij oa $post['search']
Bij beiden is de connectie ook anders opgebouwd.
Bij de procedurele moet je handmatig de boel escapen (wat je niet doet) met mysqli_real_escape_string(), en bij de object-georiënteerde gaat het vanzelf als je prepared-statements gebruikt.
Gewijzigd op 15/12/2014 22:24:41 door - Ariën -
Wat raden jullie aan? Object-georiënteerd programmeren of procedureel?
@Aar - Dus als ik het goed begrijp - Als ik alles object georienteerd schrijf dan ben ik veilig?
Bijvoorbeeld:
Lijn 31: mysqli_connect vervangen door new mysqli
enz...
dan moet ik geen mysqli_real_escape_string() meer gebruiken
Hoe is de rest? Is mijn opbouw "wat" correct?
Als ik nog een goede tip mag geven: Kopieer niet onnodig variabelen op lijn 62 t/m 65. Het is nergens voor nodig.
Thx alvast Aar!
Waarom zou je dat willen doen? Die $_POST variabelen heb je toch al, en die kan je toch prima gebruiken ;-)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(isset($_POST['Add_DB'])){
$sql="INSERT INTO customers(Voornaam, Achternaam, Adres, Actief, Discipline)
VALUES(?,?,?,NOW(),?)";
if($stmt = $dbcon->prepare($sql)){
$stmt->bind_param('sssi', $Voornaam, $Achternaam, $Adres, $Discipline);
$_POST['Voornaam'];
$_POST['Voornaam'];
$_POST['Adres'];
$_POST['Discipline'];
$stmt->execute();
$sql="INSERT INTO customers(Voornaam, Achternaam, Adres, Actief, Discipline)
VALUES(?,?,?,NOW(),?)";
if($stmt = $dbcon->prepare($sql)){
$stmt->bind_param('sssi', $Voornaam, $Achternaam, $Adres, $Discipline);
$_POST['Voornaam'];
$_POST['Voornaam'];
$_POST['Adres'];
$_POST['Discipline'];
$stmt->execute();
Toevoeging op 15/12/2014 23:20:16:
Gewijzigd op 15/12/2014 23:21:05 door Michael Desmadril
Als het goed is kan je die $_POST variabelen prima in je bind_param gebruiken.
Ok...ergens begrijp ik je maar waar vermeld ik ergens nog wat $Voornaam is....ik gebruik die variabele nergens anders toch? Als ik het formulier verstuur dan staat er data in mijn velden op het formulier. Hoe weten die nu dat ze moeten toegewezen worden aan de variabele $Voornaam...
Die variabelen in bind_param worden daar juist aangemaakt, en moeten een waarde krijgen. Dus het was juist wel goed. Even de code reverten naar de oude situatie dus.
Het is natuurlijk wel zo lelijk als het maar kan...
2) op regel 39 van het eerste script kan in SQL Injecteren aangezien je $Naam klakeloos in de SQL statement plakt.
3) leer jezelf of ALTIJD prepared statements te gebruiken.
PS. prepared statements zijn dus ook mogelijk met procedureel gebruik van de MySQLi extensie.
@ Dos -> op puntje 2) -> Hoe moet ik daar mezelf beveiligen? escape_string?
Er bestaan nog niet zoveel boeken over Mysqli...mag ik nog boeken gebruiken over mysql om dan zelf te converten naar Mysqli of is dit bad practice?
Groeten!
Nee met prepared statements:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$naam= "Frank";
/* prepared statement */
if ($stmt = mysqli_prepare($dbcon, "SELECT voornaam, achternaam, adres FROM customers WHERE voornaam=?")) {
/* bind parameters */
mysqli_stmt_bind_param($stmt, 's', $naam);
/* execute query */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $voornaam, $achternaam, $adres);
/* fetch value */
mysqli_stmt_fetch($stmt);
printf("%s %s %s\n", $voornaam, $achternaam, $adres);
/* close statement */
mysqli_stmt_close($stmt);
}
?>
$naam= "Frank";
/* prepared statement */
if ($stmt = mysqli_prepare($dbcon, "SELECT voornaam, achternaam, adres FROM customers WHERE voornaam=?")) {
/* bind parameters */
mysqli_stmt_bind_param($stmt, 's', $naam);
/* execute query */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $voornaam, $achternaam, $adres);
/* fetch value */
mysqli_stmt_fetch($stmt);
printf("%s %s %s\n", $voornaam, $achternaam, $adres);
/* close statement */
mysqli_stmt_close($stmt);
}
?>
>> Er bestaan nog niet zoveel boeken over Mysqli.
Heb je niet nodig joh. Koop dan een boek over (My)Sql in het algemeen. Dan leer je tenminste over vele mogelijkheden die Mysql je biedt.
Ik kwam trouwens onlangs een heel aardig engels ebook tegen die je zo kan downloaden: http://it-ebooks.info/book/3818/
Toevoeging op 16/12/2014 09:31:21:
Nog even een paar kleine aanmerkingen:
1) Algemene richtlijn is om variabelen zonder hoofdletter te starten. Bijv $voornaam maar ook $contentArray
2) tabelnamen en kolomnamen zie je meestal ook in uitsluitend kleine letters alhoewel dit zeker geen wet is.
Daarnaast valt me op dat je met engelse en nederlandse termen door elkaar werkt. Hou gewoon één taal aan en bij voorkeur engels.
Nogmaals het zijn geen wetten maar wel goede gebruiken.
Wanneer ik echt aan het werk ga, dan hou ik me uiteraard aan die regels! Goeie opmerking wel.
Ik heb dit boek die je voorgesteld hebt nu besteld bij Bol.com nadat ik het ingekeken heb op de pdf. Ik werk liever met iets voor me. Kwestie van beter te onthouden.
Toevoeging op 16/12/2014 11:58:00:
Voila...
Trekt dit op iets meer?
HTML
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
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<link rel="stylesheet" href="style.css">
<link href='http://fonts.googleapis.com/css?family=Raleway:200' rel='stylesheet' type='text/css'>
<script src="script.js"></script>
</head>
<body>
<table class="table_form">
<form method="POST" action="homes.php">
<tr>
<td>Voornaam: </td><td><input type="text" name="Voornaam"></td>
</tr>
<tr>
<td>Achternaam: </td><td><input type="text" name="Achternaam"></td>
</tr>
<tr>
<td>Adres: </td><td><input type="text" name="Adres"></td>
</tr>
<tr>
<td>Discipline: </td><td><input type="text" name="Discipline"></td>
</tr>
<tr>
<td>Voeg toe aan databank: </td><td><input type="submit" name="Adddb" value="Bevestigen"></td>
</tr>
</form>
</table>
<?php
require_once 'isset.php';
?>
</body>
</html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<link rel="stylesheet" href="style.css">
<link href='http://fonts.googleapis.com/css?family=Raleway:200' rel='stylesheet' type='text/css'>
<script src="script.js"></script>
</head>
<body>
<table class="table_form">
<form method="POST" action="homes.php">
<tr>
<td>Voornaam: </td><td><input type="text" name="Voornaam"></td>
</tr>
<tr>
<td>Achternaam: </td><td><input type="text" name="Achternaam"></td>
</tr>
<tr>
<td>Adres: </td><td><input type="text" name="Adres"></td>
</tr>
<tr>
<td>Discipline: </td><td><input type="text" name="Discipline"></td>
</tr>
<tr>
<td>Voeg toe aan databank: </td><td><input type="submit" name="Adddb" value="Bevestigen"></td>
</tr>
</form>
</table>
<?php
require_once 'isset.php';
?>
</body>
</html>
php/sql
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
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
<?php
require_once 'login.php';
$db_con= new mysqli($db_host, $db_username, $db_password, $db_database);
if($db_con->connect_error) die ("(" . $db_con->connect_error . " Error during connection");
if(isset($_POST['Adddb'])){
$stmt = $db_con->prepare("INSERT INTO customers (Voornaam, Achternaam, Adres, Actief, Discipline) VALUES(?,?,?,NOW(),?)");
$stmt->bind_param("sssi",$voornaam, $achternaam, $adres, $discipline);
$voornaam = $_POST['Voornaam'];
$achternaam = $_POST['Achternaam'];
$adres = $_POST['Adres'];
$discipline = $_POST['Discipline'];
$stmt->execute();
echo "New records created successfully";
$stmt->close();
$db_con->close();
}
?>
require_once 'login.php';
$db_con= new mysqli($db_host, $db_username, $db_password, $db_database);
if($db_con->connect_error) die ("(" . $db_con->connect_error . " Error during connection");
if(isset($_POST['Adddb'])){
$stmt = $db_con->prepare("INSERT INTO customers (Voornaam, Achternaam, Adres, Actief, Discipline) VALUES(?,?,?,NOW(),?)");
$stmt->bind_param("sssi",$voornaam, $achternaam, $adres, $discipline);
$voornaam = $_POST['Voornaam'];
$achternaam = $_POST['Achternaam'];
$adres = $_POST['Adres'];
$discipline = $_POST['Discipline'];
$stmt->execute();
echo "New records created successfully";
$stmt->close();
$db_con->close();
}
?>
Gewijzigd op 16/12/2014 11:58:48 door Michael Desmadril
- Voeg ook even dit toe nadat je connectie gemaakt is:
Ik ga nu onder mijn form (gewoon ter test) proberen een sectie te voorzien om de data in te lezen
Zoeken op naam.
Is het mogelijk om alles uit te lezen en dan bij de resultaten een delete knop te laten verschijnen? Is dit mogelijk? Dat je bijvoorbeeld zoekt op iedereen die "Peter" noemt en vanaf dat er resultaten zijn, dat ernaast een button staat "Delete record" bijvoorbeeld. Geen resultaten -> geen knop. Of is dit eerder iets js?
Is mogelijk.
Waar plaats ik dan mijn <input type="submit" name="delete" value="delete record" />?
Bij value is het makkelijker om daar het id in te zetten.
Hoe bedoel je San? Welk id moet ik zetten bij value?