Hacker-aanval
Zojuist is een van mijn websites slachtoffer geworden van wellicht een hacker. Gelukkig hebben we een back-up van onze database want een van de tabellen is massaal overschreven met onzin.
Om dit in de toekomst te voorkomen vraag ik jullie hulp aangaande de code die ik hanteer om mijn database bij te werken. Ik weet nl via welke pagina dit is gebeurd.
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
if($cKnop == $cKnoptekst2a) { // Invullen adresgegevens
$cExtra = "Invullen adresgegevens";
// Systeem inlezen
include "include/connectie_nw.inc.php";
$cSub = "Afronden bestelling";
include "include/systeem_nw.inc.php";
$lIngevuld = TRUE;
$_SESSION['ingevuld'] = $lIngevuld;
// Gegevens klant verzamelen en opslaan
$cVoorletters = TekstInKapitaal($_POST['voorletters']);
$cTussenvoeg = TekstinOndercast($_POST['tussenvoeg']);
$cNaam = ucwords($_POST['naam']);
$cFactuuradres = ucwords(strtolower($_POST['factuuradres']));
$cFactuurcode = ConverteerPostcode($_POST['factuurcode']);
$cFactuurplaats = TekstInKapitaal($_POST['factuurplaats']);
$cTelefoon = $_POST['telefoon'];
$cEmailadres = TekstinOndercast($_POST['emailadres']);
// Controle op PUNT achter voorletter
if(substr($cVoorletters,-1,1) != ".") {
$cVoorletters .= ".";
}
// Testen op e-mailadres van klant al in database voorkomt
include "include/connectie_nw.inc.php";
$sql = "SELECT email FROM shop__klanten WHERE email = '$cEmailadres' AND wismarkering = 0";
$cResultTestEmail = mysqli_query($verbinding,$sql);
$nAantalRecords = mysqli_num_rows($cResultTestEmail);
if($nAantalRecords == 0 ) { // E-mailadres komt niet voor, voeg klantnaam toe
if(isset($_SERVER['REMOTE_ADDR'])) {
$cIpadres = $_SERVER['REMOTE_ADDR'];
} else {
$cIpadres = "Onbekend";
}
$sql = "INSERT INTO
shop__klanten
(
voorletters,
tussenvoeg,
achternaam,
adres,
postcode,
woonplaats,
telefoon,
email,
klantnummer,
ipadres)
VALUES
(
'$cVoorletters',
'$cTussenvoeg',
'$cNaam',
'$cFactuuradres',
'$cFactuurcode',
'$cFactuurplaats',
'$cTelefoon',
'$cEmailadres',
'nieuw',
'$cIpadres'
)";
$cResultInvoer = mysqli_query($verbinding,$sql);
// ID-nummer ophalen voor toekenning aan klantnummer
$sql = "SELECT id FROM shop__klanten WHERE klantnummer = 'nieuw' AND wismarkering = 0 LIMIT 1";
$cResultKlantnummer = mysqli_query($verbinding,$sql);
$row = mysqli_fetch_array($cResultKlantnummer);
$cKlantnummer = $row['id'];
$sql = "UPDATE shop__klanten SET klantnummer = '$cKlantnummer' WHERE id = '$cKlantnummer'";
$cResultUpdate = mysqli_query($verbinding,$sql);
$_SESSION['klantnummer'] = $cKlantnummer;
mysqli_close($verbinding);
} else { // E-mailadres komt al voor in database
include "include/connectie_nw.inc.php";
$sql = "UPDATE
shop__klanten
SET
voorletters = '$cVoorletters',
tussenvoeg = '$cTussenvoeg',
achternaam = '$cNaam',
adres = '$cFactuuradres',
postcode = '$cFactuurcode',
woonplaats = '$cFactuurplaats',
telefoon = '$cTelefoon'
WHERE
email = '$cEmailadres'";
$cResultUpdate = mysqli_query($verbinding,$sql);
// ID-nummer ophalen voor toekenning aan klantnummer
$sql = "SELECT klantnummer FROM shop__klanten WHERE email = '$cEmailadres' AND wismarkering = 0 LIMIT 1";
$cResultKlantnummer = mysqli_query($verbinding,$sql);
$row = mysqli_fetch_array($cResultKlantnummer);
$cKlantnummer = $row['klantnummer'];
$_SESSION['klantnummer'] = $cKlantnummer;
mysqli_close($verbinding);
}
$cExtra = "Invullen adresgegevens";
// Systeem inlezen
include "include/connectie_nw.inc.php";
$cSub = "Afronden bestelling";
include "include/systeem_nw.inc.php";
$lIngevuld = TRUE;
$_SESSION['ingevuld'] = $lIngevuld;
// Gegevens klant verzamelen en opslaan
$cVoorletters = TekstInKapitaal($_POST['voorletters']);
$cTussenvoeg = TekstinOndercast($_POST['tussenvoeg']);
$cNaam = ucwords($_POST['naam']);
$cFactuuradres = ucwords(strtolower($_POST['factuuradres']));
$cFactuurcode = ConverteerPostcode($_POST['factuurcode']);
$cFactuurplaats = TekstInKapitaal($_POST['factuurplaats']);
$cTelefoon = $_POST['telefoon'];
$cEmailadres = TekstinOndercast($_POST['emailadres']);
// Controle op PUNT achter voorletter
if(substr($cVoorletters,-1,1) != ".") {
$cVoorletters .= ".";
}
// Testen op e-mailadres van klant al in database voorkomt
include "include/connectie_nw.inc.php";
$sql = "SELECT email FROM shop__klanten WHERE email = '$cEmailadres' AND wismarkering = 0";
$cResultTestEmail = mysqli_query($verbinding,$sql);
$nAantalRecords = mysqli_num_rows($cResultTestEmail);
if($nAantalRecords == 0 ) { // E-mailadres komt niet voor, voeg klantnaam toe
if(isset($_SERVER['REMOTE_ADDR'])) {
$cIpadres = $_SERVER['REMOTE_ADDR'];
} else {
$cIpadres = "Onbekend";
}
$sql = "INSERT INTO
shop__klanten
(
voorletters,
tussenvoeg,
achternaam,
adres,
postcode,
woonplaats,
telefoon,
email,
klantnummer,
ipadres)
VALUES
(
'$cVoorletters',
'$cTussenvoeg',
'$cNaam',
'$cFactuuradres',
'$cFactuurcode',
'$cFactuurplaats',
'$cTelefoon',
'$cEmailadres',
'nieuw',
'$cIpadres'
)";
$cResultInvoer = mysqli_query($verbinding,$sql);
// ID-nummer ophalen voor toekenning aan klantnummer
$sql = "SELECT id FROM shop__klanten WHERE klantnummer = 'nieuw' AND wismarkering = 0 LIMIT 1";
$cResultKlantnummer = mysqli_query($verbinding,$sql);
$row = mysqli_fetch_array($cResultKlantnummer);
$cKlantnummer = $row['id'];
$sql = "UPDATE shop__klanten SET klantnummer = '$cKlantnummer' WHERE id = '$cKlantnummer'";
$cResultUpdate = mysqli_query($verbinding,$sql);
$_SESSION['klantnummer'] = $cKlantnummer;
mysqli_close($verbinding);
} else { // E-mailadres komt al voor in database
include "include/connectie_nw.inc.php";
$sql = "UPDATE
shop__klanten
SET
voorletters = '$cVoorletters',
tussenvoeg = '$cTussenvoeg',
achternaam = '$cNaam',
adres = '$cFactuuradres',
postcode = '$cFactuurcode',
woonplaats = '$cFactuurplaats',
telefoon = '$cTelefoon'
WHERE
email = '$cEmailadres'";
$cResultUpdate = mysqli_query($verbinding,$sql);
// ID-nummer ophalen voor toekenning aan klantnummer
$sql = "SELECT klantnummer FROM shop__klanten WHERE email = '$cEmailadres' AND wismarkering = 0 LIMIT 1";
$cResultKlantnummer = mysqli_query($verbinding,$sql);
$row = mysqli_fetch_array($cResultKlantnummer);
$cKlantnummer = $row['klantnummer'];
$_SESSION['klantnummer'] = $cKlantnummer;
mysqli_close($verbinding);
}
Hoe kan ik de code beter maken zodat alles in het werk is gesteld om meer ellende te voorkomen?
Kijk eens naar functies als myqli_real_escape_string() htmlentities() htmlspecialchars()
Ik veronderstel dat dit van de eerste letter een hoofdletter maakt, of zo.
[een beetje off topic] Je zou dit trouwens niet mogen doen. Jij mag geen gegevens, die jouw gebruikers invullen, veranderen. [/een beetje off topic]
Wat zo'n functie zou moeten doen, is escapen.
$cVoorletters = mysql_real_escape_string($_POST['voorletters']);
$cTussenvoeg = mysql_real_escape_string($_POST['tussenvoeg']);
...
Escapen houdt aanvallen met SQL-injection tegen.
(Ik merk trouwens dat je al meerdere vragen stelde ivm. SQL, maar nooit iets gepost hebt waar je de SQL en de PHP-code samen toont. Anders hadden we jou daar al heel lang over aangesproken)
Gewijzigd op 12/11/2013 16:19:33 door Kris Peeters
Alleen SQL-injectie tegengaan, zal hier niet helpen. De database vullen met onzin blijft door dit soort logicafouten mogelijk.
Ga ik eerst doen. Op de opmerkingen van Wart kom ik later terug.
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
// Gegevens klant verzamelen en opslaan
$cVoorletters = TekstInKapitaal(mysqli_real_escape_string($verbinding,$_POST['voorletters']));
$cTussenvoeg = TekstinOndercast(mysqli_real_escape_string($verbinding,$_POST['tussenvoeg']));
$cNaam = ucwords(mysqli_real_escape_string($verbinding,$_POST['naam']));
$cFactuuradres = ucwords(mysqli_real_escape_string(strtolower($verbinding,$_POST['factuuradres'])));
$cFactuurcode = ConverteerPostcode( mysqli_real_escape_string($verbinding,$_POST['factuurcode']));
$cFactuurplaats = TekstInKapitaal(mysqli_real_escape_string($verbinding,$_POST['factuurplaats']));
$cTelefoon = mysqli_real_escape_string($verbinding,$_POST['telefoon']);
$cEmailadres = TekstinOndercast(mysqli_real_escape_string($verbinding,$_POST['emailadres']));
$cVoorletters = TekstInKapitaal(mysqli_real_escape_string($verbinding,$_POST['voorletters']));
$cTussenvoeg = TekstinOndercast(mysqli_real_escape_string($verbinding,$_POST['tussenvoeg']));
$cNaam = ucwords(mysqli_real_escape_string($verbinding,$_POST['naam']));
$cFactuuradres = ucwords(mysqli_real_escape_string(strtolower($verbinding,$_POST['factuuradres'])));
$cFactuurcode = ConverteerPostcode( mysqli_real_escape_string($verbinding,$_POST['factuurcode']));
$cFactuurplaats = TekstInKapitaal(mysqli_real_escape_string($verbinding,$_POST['factuurplaats']));
$cTelefoon = mysqli_real_escape_string($verbinding,$_POST['telefoon']);
$cEmailadres = TekstinOndercast(mysqli_real_escape_string($verbinding,$_POST['emailadres']));
Toevoeging op 12/11/2013 17:22:13:
De logica-fout waarop Ward mij aansprak heb ik onderkend en als volgt gewijzigd:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
} else { // E-mailadres komt al voor in database
include "include/connectie_nw.inc.php";
// ID-nummer ophalen voor toekenning aan klantnummer
$sql = "SELECT klantnummer FROM shop__klanten WHERE email = '$cEmailadres' AND wismarkering = 0 LIMIT 1";
$cResultKlantnummer = mysqli_query($verbinding,$sql);
$row = mysqli_fetch_array($cResultKlantnummer);
$cKlantnummer = $row['klantnummer'];
$_SESSION['klantnummer'] = $cKlantnummer;
mysqli_close($verbinding);
}
include "include/connectie_nw.inc.php";
// ID-nummer ophalen voor toekenning aan klantnummer
$sql = "SELECT klantnummer FROM shop__klanten WHERE email = '$cEmailadres' AND wismarkering = 0 LIMIT 1";
$cResultKlantnummer = mysqli_query($verbinding,$sql);
$row = mysqli_fetch_array($cResultKlantnummer);
$cKlantnummer = $row['klantnummer'];
$_SESSION['klantnummer'] = $cKlantnummer;
mysqli_close($verbinding);
}
Toevoeging op 12/11/2013 17:23:45:
In mijn geval heeft de ongewenste bezoeker alle namen en adressen gewijzigd in de klantentabel. Hoe kan ik zoiets voorkomen?
Toevoeging op 12/11/2013 18:08:22:
Nu heb ik dus de $_POST-variabelen via een mysqli_real_escape_string opgeslagen maar moet dit ook voor het onderstaande voorbeeld?
Code (php)
1
2
3
2
3
//Koop definitief
$sql = "UPDATE shop__winkelwagen SET koopdefinitief = 'Ja', koopmoment = NOW() WHERE ordernummer = '$cOrdernummer'";
$cResultKoop = mysqli_query($verbinding,$sql);
$sql = "UPDATE shop__winkelwagen SET koopdefinitief = 'Ja', koopmoment = NOW() WHERE ordernummer = '$cOrdernummer'";
$cResultKoop = mysqli_query($verbinding,$sql);
In dit voorbeeld wordt een veld dus met de waarde van een variabele gevuld. Een ander voorbeeld staat hieronde:
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
while($row = mysqli_fetch_array($cResultWinkelwagen)) {
$cArtikelnummer = $row['productnummer'];
$_SESSION['artikelnummer'] = $cArtikelnummer;
$cPrijs = $row['prijs'];
$cOpmerking = $row['opmerking'];
$nAantal = 1;
$nBTW = $cPrijs-(100/(100+$_SESSION['btw']) * $cPrijs);
// Toevoegen aan bestellingen
$cKlantnummer = $_SESSION['klantnummer'];
$sql = "INSERT INTO shop__bestellingen (artikelnummer,klantnummer,aantal,factuurbedrag,btw,besteldatum,ordernummer,factuurdatum,opmerking)
VALUES('$cArtikelnummer','$cKlantnummer','$nAantal','$cPrijs','$nBTW',NOW(),'$cOrdernummer',NOW(),'$cOpmerking');";
$cResultBestelling = mysqli_query($verbinding,$sql);
}
$cArtikelnummer = $row['productnummer'];
$_SESSION['artikelnummer'] = $cArtikelnummer;
$cPrijs = $row['prijs'];
$cOpmerking = $row['opmerking'];
$nAantal = 1;
$nBTW = $cPrijs-(100/(100+$_SESSION['btw']) * $cPrijs);
// Toevoegen aan bestellingen
$cKlantnummer = $_SESSION['klantnummer'];
$sql = "INSERT INTO shop__bestellingen (artikelnummer,klantnummer,aantal,factuurbedrag,btw,besteldatum,ordernummer,factuurdatum,opmerking)
VALUES('$cArtikelnummer','$cKlantnummer','$nAantal','$cPrijs','$nBTW',NOW(),'$cOrdernummer',NOW(),'$cOpmerking');";
$cResultBestelling = mysqli_query($verbinding,$sql);
}
Voorbeeld 1 was via een UPDATE en voorbeeld 2 via een INSERT
Gewijzigd op 12/11/2013 18:24:59 door George van Baasbank