5.1. Sikre forespørgsler

Et klassisk problem ved brugen af databaser er at få "escapet" værdier man vil sætte ind i en SQL-forespørgsel. Meget kan gå galt og man kan brænde fingrene grusomt hvis man ikke sørger for at lave uskyldig SQL.

Forventer du for eksempel et tal fra $_GET['id'] kan du brænde nallerne ved blot at lave din SQL således:

$sql = 'select * from users where id = ' . $_GET['id'];

Hvis nu en ond bruger skriver "1; delete from users" betyder det at din SQL ender med at se sådan ud:

$sql = 'select * from users where id = 1; delete from users';

Det betyder at der vil blive kørt to forespørgsler - én der trækker data ud om bruger nummer 1, og en der sletter alle brugere. Og så står du der og aner ikke hvad der ramte dig...

Den ikke så skarpe udvikler vil sige, at du blot kan sætte anførselstegn omkring:

$sql = "select * from users where id = '" . $_GET['id'] . "'";

Til dette er der blot for den onde bruger at sende følgende i $_GET['id']: "1'; delete from users where 'a' = 'a", og så ser din forespørgsel sådan ud:

$sql = "select * from users where id = '1'; delete from users where 'a' = 'a'";

Og så er du lige vidt, da a altid er lig a vil alle dine brugere igen blive slettet.

For at undgå sådanne ubehageligheder kan du sætte spørgsmålstegn ind i din SQL der hvor du vil indsætte en værdi som skal escapes, og så giver du de rå værdier med på "placeholders"-nøglen i et options-array. Som for eksempel:

$sql = 'select * from users where id = ? and status = ?';                                          
$opts = array('placeholders' => array($_GET['id'], $_GET['status']));                                                     
                                                                                                                                                                                                                 
$res = M2_SQL::query($sql, $opts);    

Nu sørger Moski2.net for at selv de ondeste mennesker skrive hvad de vil i $_GET['id'], og din SQL vil ikke foretage sig noget farligt.