Kyselyongelmat PDO:ssa PHP:ssä
Kuten jo tiedät, SQL-kyselyt ovat alttiita SQL-injektioille. PDO-laajennus on tarkoitettu torjumaan injektioita, mutta oletusarvoisesti se ei tee sitä automaattisesti.
Katsotaan ongelmaa esimerkin avulla. Oletetaan, että meillä on seuraava kysely, johon muuttuja liitetään:
<?php
$sql = "SELECT * FROM users WHERE id=$id";
$res = $pdo->query($sql);
?>
Oletetaan, että muuttujamme tulee jostakin ulkoisesta lähteestä, esimerkiksi GET-parametrista. Yksinkertaisuuden vuoksi asetetaan kuitenkin sen arvo manuaalisesti. Odottamme jonkin numeerisen arvon, esimerkiksi seuraavan:
<?php
$id = 1;
?>
Pahantahtoinen hakkeri voi kuitenkin välittää
seuraavan arvon (oletetaan, että meillä
on kenttä role):
<?php
$id = '-1 OR role="admin"';
?>
Käy niin, että halusimme seuraavan kyselyn:
<?php
$sql = "SELECT * FROM users WHERE id=1";
$res = $pdo->query($sql);
?>
Mutta saimme seuraavan, joka noutaa sivuston ylläpitäjän:
<?php
$sql = "SELECT * FROM users WHERE id=-1 OR role="admin"";
$res = $pdo->query($sql);
?>
Välttääksesi tällaisen tilanteen, PDO:ssa on valmiiksi erityinen mekanismi, jota kutsutaan valmistelluiksi kyselyiksi. Niitä käsittelemme seuraavassa oppitunnissa.
Toteuta tarkoituksella SQL-injektio tietokantaasi.