Enhver forespørgsel kan injiceres, uanset om den er læst eller skrivning, vedvarende eller forbigående. Injektioner kan udføres ved at afslutte en forespørgsel og køre en separat (mulig med mysqli
), hvilket gør den tilsigtede forespørgsel irrelevant.
Ethvert input til en forespørgsel fra en ekstern kilde, uanset om det er fra brugere eller endda internt, bør betragtes som et argument for forespørgslen og en parameter i forespørgslens kontekst. Enhver parameter i en forespørgsel skal parametreres. Dette fører til en korrekt parametriseret forespørgsel, som du kan oprette en forberedt sætning ud fra og udføre med argumenter. For eksempel:
SELECT col1 FROM t1 WHERE col2 = ?
?
er en pladsholder for en parameter. Brug af mysqli
, kan du oprette en forberedt erklæring ved hjælp af prepare
, bind en variabel (argument) til en parameter ved hjælp af bind_param
, og kør forespørgslen med execute
. Du behøver slet ikke at rense argumentet (det er faktisk skadeligt at gøre det). mysqli
gør det for dig. Den fulde proces ville være:
$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
Der er også en vigtig skelnen mellem parameteriseret forespørgsel og forberedt erklæring . Denne erklæring er, mens den er udarbejdet, ikke parametriseret og er derfor sårbar over for injektion:
$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
For at opsummere:
- Alle Forespørgsler skal parametreres korrekt (medmindre de ikke har nogen parametre)
- Alle argumenter til en forespørgsel skal behandles så fjendtligt som muligt uanset deres kilde