PHP har en indstilling, som er sat til som standard, der hedder Magic Quotes. Denne indstilling laver om på inputs, som kommer *direkte* fra brugeren, så de kan indsættes som en del af en SQL query.
Læg mærke til ordet "direkte". Variabler du selv laver er ikke beskyttet, og variabler som kommer andre steder fra er heller ikke beskyttet. Sammensætter du derefter variabler, som kommer fra brugeren, med andre variabler, resulterer det i en tekststreng, hvor noget af den er beskyttet. Samtidigt betyder det at variablerne fra brugeren kun er beregnet til SQL, og quotesne skal derfor fjernes, hvis de skal bruges andre steder. Min anbefaling: lav en htaccess-fil og slå Magic Quotes fra. Det er noget værre rod.
I kodeeksemplerne går jeg ud fra at Magic Quotes er slået fra. $db refererer til er en databaseforbindelse via PDO (
http://php.net/pdo ), $user og $pass er informationer indtastet af brugeren.
Først en query, som er åben for angreb:
<?php
$stmt = $db->query("SELECT * FROM users WHERE user = '$user' AND pass = '$pass'");
?>
Denne kan hurtigt sikres:
<?php
$sql_clean_user = $db->quote($user);
$sql_clean_pass = $db->quote($pass);
$stmt = $db->query("SELECT * FROM users WHERE user = $sql_clean_user AND pass = $sql_clean_pass");
?>
Den kan dog sikres på en langt bedre måde:
<?php
$stmt = $db->prepare("SELECT * FROM users WHERE user = :user AND pass = :pass");
$stmt->execute(
array(
':user' => $user,
':pass' => $pass
)
);
?>
Hvorfor er den sidste metode bedre? Fordi den helt undgår problemstillingen omkring SQL injections. Her skrives hele SQL-queryen som en enkelt string, der ikke sammensættes af flere variabler, og man undgår herved at variablerne sammensættes på en usikker måde.
Variablerne som bruges i arrayen skal ikke være sikrede, da databasen selv sørger for dette.
PS. Eksemplerne forudsætter brug af PDO, og kræver derfor en nyere udgave af PHP