Deze wikiHow leert je hoe je SQL-injectie kunt voorkomen met behulp van Prepared Statements in PHP. SQL-injectie is tegenwoordig een van de meest voorkomende kwetsbaarheden in webapplicaties. Voorbereide instructies gebruiken gebonden parameters en combineren geen variabelen met SQL-tekenreeksen, waardoor het voor een aanvaller onmogelijk is om de SQL-instructie te wijzigen.
Prepared Statements combineren de variabele met het gecompileerde SQL-statement, zodat de SQL en de variabelen afzonderlijk worden verzonden. De variabelen worden dan geïnterpreteerd als louter strings en maken geen deel uit van de SQL-instructie. Als u de methoden in de onderstaande stappen gebruikt, hoeft u geen andere filtertechnieken voor SQL-injectie te gebruiken, zoals de mysql_real_escape_string().
Stappen
Deel 1 van 2: SQL-injectie begrijpen
Stap 1. SQL-injectie is een type kwetsbaarheid in applicaties die gebruikmaken van een SQL-database
De kwetsbaarheid ontstaat wanneer een gebruikersinvoer wordt gebruikt in een SQL-instructie:
$name = $_GET['gebruikersnaam']; $query = "SELECTEER wachtwoord FROM tbl_user WHERE name = '$name' ";
Stap 2. De waarde die een gebruiker invoert in de URL-variabele gebruikersnaam wordt toegewezen aan de variabele $name
Het wordt dan rechtstreeks in de SQL-instructie geplaatst, waardoor de gebruiker de SQL-instructie kan bewerken.
$name = "admin' OF 1=1 -- "; $query = "SELECTEER wachtwoord FROM tbl_user WHERE name = '$name' ";
Stap 3. De SQL-database ontvangt dan het SQL-statement als volgt:
SELECTEER wachtwoord FROM tbl_users WHERE naam = 'admin' OR 1=1 -- '
-
Dit is geldige SQL, maar in plaats van één wachtwoord voor de gebruiker te retourneren, retourneert de instructie alle wachtwoorden in de tabel tbl_user. Dit wil je niet in je webapplicaties.
Deel 2 van 2: mySQLi gebruiken om voorbereide verklaringen te maken
Stap 1. Maak de mySQLi SELECT-query
Gebruik de onderstaande code om gegevens uit een tabel te SELECTEREN met behulp van mySQLi Prepared Statements.
$name = $_GET['gebruikersnaam']; if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) { // Bind een variabele aan de parameter als een string. $stmt->bind_param("s", $name); // Voer de instructie uit. $stmt->uitvoeren(); // Haal de variabelen uit de query. $stmt->bind_result($pass); // Haal de gegevens op. $stmt->fetch(); // Geef de gegevens weer. printf("Wachtwoord voor gebruiker %s is %s\n", $name, $pass); // Sluit de voorbereide verklaring. $stmt->close(); }
Opmerking: de variabele $mysqli is het mySQLi-verbindingsobject
Stap 2. Maak de mySQLi INSERT-query
Gebruik de onderstaande code om gegevens in een tabel in te voegen met behulp van mySQLi Prepared Statements.
$name = $_GET['gebruikersnaam']; $wachtwoord = $_GET['wachtwoord']; if ($stmt = $mysqli->prepare("INSERT INTO tbl_users (name, password) VALUES (?, ?)")) { // Bind de variabelen aan de parameter als strings. $stmt->bind_param("ss", $naam, $wachtwoord); // Voer de instructie uit. $stmt->uitvoeren(); // Sluit de voorbereide verklaring. $stmt->close(); }
Opmerking: de variabele $mysqli is het mySQLi-verbindingsobject
Stap 3. Maak de mySQLi UPDATE-query
Gebruik de onderstaande code om gegevens in een tabel BIJWERKEN met behulp van mySQLi Prepared Statements.
$name = $_GET['gebruikersnaam']; $wachtwoord = $_GET['wachtwoord']; if ($stmt = $mysqli->prepare("UPDATE tbl_users SET password = ? WHERE name = ?")) { // Bind de variabelen aan de parameter als strings. $stmt->bind_param("ss", $wachtwoord, $naam); // Voer de instructie uit. $stmt->uitvoeren(); // Sluit de voorbereide verklaring. $stmt->close(); }
Opmerking: de variabele $mysqli is het mySQLi-verbindingsobject
Stap 4. Maak de mySQLi DELETE-query
Het onderstaande script laat zien hoe u gegevens uit een tabel kunt VERWIJDEREN met behulp van door mySQLi voorbereide instructies.
$name = $_GET['gebruikersnaam']; $wachtwoord = $_GET['wachtwoord']; if ($stmt = $mysqli->prepare("DELETE FROM tbl_users WHERE name = ?")) { // Bind de variabele aan de parameter als een string. $stmt->bind_param("s", $name); // Voer de instructie uit. $stmt->uitvoeren(); // Sluit de voorbereide verklaring. $stmt->close(); }