Vilken fråga som helst kan injiceras oavsett om den är läs eller skriv, ihållande eller övergående. Injektioner kan utföras genom att avsluta en fråga och köra en separat (möjligt med mysqli
), vilket gör den avsedda frågan irrelevant.
All input till en fråga från en extern källa, oavsett om den är från användare eller till och med intern, bör betraktas som ett argument för frågan och en parameter i frågans sammanhang. Alla parametrar i en fråga måste parametriseras. Detta leder till en korrekt parametriserad fråga som du kan skapa en förberedd sats från och köra med argument. Till exempel:
SELECT col1 FROM t1 WHERE col2 = ?
?
är en platshållare för en parameter. Använder mysqli
, kan du skapa en förberedd sats med prepare
, bind en variabel (argument) till en parameter med bind_param
, och kör frågan med execute
. Du behöver inte sanera argumentet alls (det är faktiskt skadligt att göra det). mysqli
gör det åt dig. Hela processen skulle vara:
$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
Det finns också en viktig skillnad mellan parameteriserad fråga och förberedt uttalande . Detta uttalande, medan det är förberett, är inte parametriserat och är därför sårbart för injektion:
$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
För att sammanfatta:
- Alla Frågor bör parametreras korrekt (såvida de inte har några parametrar)
- Alla argument till en fråga bör behandlas så fientligt som möjligt oavsett källa