Dag allemaal,
In deze tutorial ga ik jullie wat proberen bij te leren over beveiliging in PHP.
Als je een website programmeert is het belangrijk dat deze veilig is.
Je zou natuurlijk niet willen dat deze wordt gehackt.
Ik probeer alles zo goed mogelijk uit te leggen!
1. SQL injection
Een SQL injectie is een kwetsbaarheid waarmee de hacker de volledige database mee kan uitlezen.
Hoewel dit lek rond het jaar 2000 al bekend is zijn er nog steeds websites die kwetsbaar zijn voor een SQL injectie.
Hoe gaat een SQL injectie dan in zijn werk?
Voorbeeld code kwetsbaar voor SQL injections
<?php
// Deze gaat nakijken over er achter nieuws.php wel ?id= staat anders kunnen we het nieuws niet inladen!
if(isset($_GET['newsID'])) {
// Het aangevraagde nieuws id
$newsID = $_GET['newsID'];
$title = $_GET['title'];
// Haalt het nieuws bericht op in onze database
$query = mysqli_query($conn,"SELECT id,title,content FROM _news WHERE id=$newsID AND title='$title' ") or die(mysqli_error($conn));
// Nu gaan we alle rows uit onze tabel halen
while($row = mysqli_fetch_assoc($query)) {
// Toont het bericht op het scherm!
printf("Nieuws met als titel: %s <br> %s",$row['title'],$row['content']);
}
}
De bovenstaande code is kwetsbaar voor een SQL injectie. Als ik nu pagina.php?newsID=1
doe zal er niets gebeuren maar zodra ik een quote achter de 1 type zal er een mysql error getoont worden. Want php zal alles wat je in newsID=
plaatst letterlijk in de query zetten.
De onderstaande code zal een SQL injectie tegen gaan!
<?php
$conn = mysqli_connect('localhost', 'root', '', 'vulnerable');
// Deze gaat nakijken over er achter nieuws.php wel ?id= staat anders kunnen we het nieuws niet inladen!
if(isset($_GET['newsID'])) {
// Het aangevraagde nieuws id
$newsID = (int)$_GET['newsID']; // Bij een int gebruik!
$title = mysqli_real_escape_string($conn,$_GET['title']); // Bij een string gebruik je deze!
// Haalt het nieuws bericht op in onze database
$query = mysqli_query($conn,"SELECT id,title,content FROM _news WHERE id=$newsID AND title='$title' ") or die(mysqli_error($conn));
// Nu gaan we alle rows uit onze tabel halen
while($row = mysqli_fetch_assoc($query)) {
// Toont het bericht op het scherm!
printf("Nieuws met als titel: %s <br> %s", $row['title'], $row['content']);
}
}
De bovenstaande code was de oplossing tegen een MySQL injection.
2. XSS attack
De volgende in de lijst is een XSS attack. Met een XSS attack kan een kwaadwillende code in de website plaatsen om zo cookies te stelen of kan hij iets in de website aanbrengen waardoor hij achter jouw wachtwoord kan komen.
Voorbeeld code kwetsbaar voor XSS
<?php
if(isset($_GET['message'])) {
echo $_GET['message'];
}
Als de hacker nu pagina.php?message=<iframe src="http://kwaadaardigewebsite.com/login.php" width="188" height="258">
doe zal er een login scherm verschijnen in de website.
De oplossing tegen een XSS attack.
<?php
if(isset($_GET['message'])) {
echo htmlspecialchars($_GET['message']);
}
3. Local File Inclusion (LFI)
Local File Inclusion is een gevaarlijke kwetsbaarheid hiermee kan de hacker alle bestanden op de server uitlezen.
Voorbeeld code kwetsbaar voor Local File Inclusion
<?php
if(isset($_GET['page'])) {
$page = $_GET['page'];
//Kijken of de pagina wel bestaat
if(file_exists($page)) {
include_once $page;
}else {
die('pagina niet gevonden!');
}
}
Wat kan een hacker nu doen? Normaal zal de url iets zijn zoals /index.php?page=home.php
zoals als je ziet vragen we het bestand home.php op.
Maar doordat we niet checken welk bestand de gebruiker opvraagt kan hij gewoon alle bestanden in de server opvragen. Om een voorbeeld te
nemen /index.php?page=../../etc/passwd
de hacker zou zo achter configuratie bestanden of backups kunnen komen en dat is uiteraard niet de bedoeling.
Een mogelijke oplossing:
<?php
if(isset($_GET['page'])) {
$page = $_GET['page'];
switch($page){
case 'home':
include_once 'home.php';
break;
default:
die('Niet gevonden!');
}
}
Arbitrary File Download
Met een Arbitrary File Download exploit kan een gebruiker alle bestanden van de server downloaden.
Vorig jaar heb ik zo nog een lek gevonden in Smartschool dus je ziet dat het ook in grote website's voorkomt.
Voorbeeld kwetsbare code
<?php
if(isset($_GET['streamPath'])) {
$path = $_GET['streamPath'];
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=".$path." ");
echo readfile($path);
}
Als de kwaadwillende nu bijvoorbeeld download.php?streamPath=
kan de gebruiker alle bestanden van de server downloaden en zo zelfs aan database wachtwoorden komen.
Hoe beveilig ik mij hiertegen? Simpel altijd goed valideren welke bestanden de gebruiker download.
Tot slot
Wow, bedankt dat je tot hier hebt gelezen. Ik hoop dat ik in deze tutorial jullie wat heb kunnen bijleren over beveiliging.
Er zijn inderdaad nog tal van lekken! Ben ik iets vergeten of heb ik iets niet goed uitgelegd mag je mij altijd verbeteren.