Wat is SQL-injectie en hoe voorkom je dit in PHP?
SQL-injectie is een veelvoorkomende kwetsbaarheid in webapplicaties waarbij een aanvaller kwaadaardige SQL-code invoegt in een query, uitgevoerd door de database. Dit kan leiden tot ongeautoriseerde toegang tot de gegevens, gegevensdiefstal, modificatie of zelfs volledige vernietiging van de gegevens.
Bij SQL-injectie maakt de aanvaller gebruik van invoervelden die onvoldoende worden gevalideerd en ontsmet om zijn schadelijke SQL-opdrachten door te sturen naar de achterliggende database. Dit kan bijvoorbeeld via een loginformulier, zoekvelden of URL’s.
Stel, we hebben een eenvoudig PHP-script dat een gebruikersnaam en wachtwoord controleert:
```
$username = $_POST[‘username’];
$password = $_POST[‘password’];
$sql = “SELECT * FROM users WHERE username=’$username’ AND password=’$password’”;
$result = mysqli_query($conn, $sql);
?>
```
Een aanvaller zou de invoer kunnen manipuleren als volgt:
```
$username = ‘admin’ — ‘;
$password = ‘wachtwoord’;
```
Dit produceert de volgende SQL-query:
```
SELECT * FROM users WHERE username=‘admin’— ‘ AND password=‘wachtwoord’;
```
De `—` commentaar markering zorgt ervoor dat de rest van de query wordt genegeerd. De aanval resulteert in de volgende effectieve query:
```
SELECT * FROM users WHERE username=‘admin’;
```
Hierdoor kan de aanvaller mogelijk toegang krijgen tot het account van de admin zonder het correcte wachtwoord.
1. Gebruik Prepared Statements en Parameter Binding:
Prepared statements zorgen ervoor dat de SQL-query en de parameters strikt gescheiden blijven, waardoor het niet mogelijk is voor een aanvaller om de query-structuur te manipuleren. Voorbeeld met MySQLi: \`\`\`php prepare(“SELECT \* FROM users WHERE username = ? AND password = ?”); $stmt->bind\_param(“ss”, $username, $password); $stmt->execute(); $result = $stmt->get\_result(); ?> \`\`\` Voorbeeld met PDO: \`\`\`php prepare(“SELECT \* FROM users WHERE username = :username AND password = :password”); $stmt->bindParam(‘:username’, $username); $stmt->bindParam(‘:password’, $password); $stmt->execute(); $result = $stmt->fetchAll(); ?> \`\`\`1. Ontsmetten van Invoer:
Zorg ervoor dat alle gebruikersinvoer wordt ontsmet met functies zoals `mysqli_real_escape_string()` voor MySQLi of `htmlspecialchars()` voor alternatieve ontsmetting. \`\`\`php \`\`\`1. Gebruik van WAF (Web Application Firewall):
Een WAF kan helpen om verdachte verkeerspatronen en kwaadaardige payloads te detecteren en blokkeren voordat ze je applicatie bereiken.1. Minimale Database Privileges:
Zorg ervoor dat de databasegebruiker die door de applicatie wordt gebruikt, minimale privileges heeft. Dus enkel lees- en schrijfrechten die nodig zijn voor de context.1. Input Validatie:
Controleer dat de invoer voldoet aan de verwachte format- en typevereisten. Bijvoorbeeld, voor een gebruikersnaam, zorg dat deze alleen alfanumerieke tekens bevat.1. Regelmatige Updates en Patches:
Zorg ervoor dat zowel de database- als serverbeveiligingssoftware regelmatig wordt bijgewerkt met de nieuwste beveiligingspatches.
- OWASP: Top 10 Security Vulnerabilities. Beschikbaar op: https://owasp.org/www-project-top-ten/
- PHP officiële documentatie: Prepared Statements. Beschikbaar op: https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
- PDO specifieke documentatie: Prepared Statements and Bound Parameters. Beschikbaar op: https://www.php.net/manual/en/pdo.prepared-statements.php
Deze maatregelen zijn essentieel om je PHP-applicatie te beschermen tegen SQL-injecties en de veiligheid van je gegevens te waarborgen.