Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: [MySQL] Käyttäjän syöte sisältää '-merkin

Sivun loppuun

Petja [13.02.2011 15:26:21]

#

Jos nyt otetaan esimerkiksi hakuskripti. Käyttäjä kirjoittaa hakuruutuun tekstiä ja painaa ENTER, jolloin tiedot laitetaan eteenpäin. Käyttäjä on voinut täydentää hakusanaansa esimerkiksi '- ja ´-merkein, jolloin oletettavasti palautetaan virhe. Miten vältän siis virheen, vaikka käyttäjä laittaisi '-merkin hakusanaansa? Toki voin PHP:llä karsia kyseiset merkit pois, mutta onko muita "häiritseviä" merkkejä kuin ' ja ´.

Selkeytettynä siis:
WHERE Jotain = 'Haku'sanani' palauttaisi virheen

Grez [13.02.2011 15:44:09]

#

No ei siinä mitään että palauttaa virheen, mutta mitäpä jos se kirjoittaisikin siihen vaikka:
' OR ''='

Näin voisi tulla sellaisetkin rivit mitä ei haluta näyttää.

Olet siis toteuttanut tietoturva-aukon jota kutsutaan SQL-injektioksi. Kannattaa tutustua miten siltä vältytään. Aiheesta: http://xkcd.com/327/

Yksi hyvä apuväline on mysql_real_escape_string tai jonkin ORMin tai parametrisoituja kyselyitä käyttävän kirjaston käyttö.

Petja [13.02.2011 15:52:52]

#

Öhm... Pystyykö tätä selittämään mitenkään selvemmin? :O

Ja tuosta antamastasi osoitteesta löysin vaan jonkun sarjakuvastripin. En tiedä miten se nyt tähän liittyy. Kertoo taulun poistamisesta?

Grez [13.02.2011 15:58:45]

#

Petja kirjoitti:

Öhm... Pystyykö tätä selittämään mitenkään selvemmin? :O

No, jos ei kiinnosta ymmärtää mitä on tekemässä niin riittää kun laitat sen syötteen mysql_real_escape_string funktion läpi.

Petja kirjoitti:

Kertoo taulun poistamisesta?

Niin, periaatteessa tapasi kirjoittaa koodia mahdollistaisi kenelle tahansa sivulliselle taulun poistamisen tietokannasta, jos vaan arvaa taulun nimen.

Onneksesi PHP ei kuitenkaan salli useamman kyselyn suorittamista samalla mysql_query:llä.

Petja [13.02.2011 16:02:11]

#

Aaa... Eli siis:

mysql_real_escape_string("Kysely tulee tähän...");
mysql_query .....

Ymmärsin oikein?
En?

Grez [13.02.2011 16:06:18]

#

Ei kun se pelkkä käyttäjän syöte, ei koko kyselystringiä.

Eli esim.

$sql = "SELECT Blaa FROM Blöö WHERE Jotain='" .
  mysql_real_escape_string($_POST['Haku']) . "'";
$result = mysql_query($sql);

Ihan vinkkinä vastaisen varalle, että jos joku neuvoo käyttämään jotain funktiota, niin PHP:n funktioiden ohessa on usein esimerkkikoodia, ja tässäkin tapauksessa oikea tapa käyttää funktiota olisi sieltäkin löytynyt: https://www.php.net/manual/en/function.mysql-real-escape-string.php

The Alchemist [13.02.2011 18:11:31]

#

PDO on nykyaikaa. Ei enää kannata itse ruveta säätämään kyselyjen turvaamisen kanssa.

Kyselyn suorittaminen PDO:lla menisi suurin piirtein näin:

*** TAPA I ***

$db = new PDO('mysql:dbname=Mun_Kanta', $username, $password);
$q = $db->prepare('SELECT id, phone, address FROM users WHERE name = ?');
$q->bindParam(1, $_GET['userData'], PDO::PARAM_STR); // Huomaa 1-indeksointi!
$q->execute();
$results = $q->fetchAll(PDO::FETCH_ASSOC);

foreach ($results as $r) {
  printf("ID: %d, osoite: %s, puhelin: %s\n", $r['id'], $r['address'], $r['phone']);
}
*** TAPA II ***

$db = new PDO('mysql:dbname=Mun_Kanta', $username, $password);
$q = $db->prepare('SELECT id, phone, address FROM users WHERE name = :nimi');
$q->execute( array(':nimi' => $_GET['user']) );
$results = $q->fetchAll(PDO::FETCH_ASSOC);
...

Syötettävän datan kelvollisuutta ei prepare-metodia käyttäessä itse varmistaa mitenkään. Kyselyt voi myös suorittaa suoraan PDO::query()-funktiolla, mutta tällöin varmistus tulee tehdä itse esim. PDO::quote'lla.

Grez [13.02.2011 18:37:31]

#

IMO, relaatiokantojen kanssa ORMit on nykyaikaa.

Mutta toki PDO on tyhjää parempi, varsinkin kun PHP on oliokieleksi (ja muutenkin) onneton (jälleen IMO). Eli PHP:llä ei todellakaan saa ORMeista kaikkea iloa irti. PDO:han viittasinkin jo tuossa alkuperäisessa vastauksessani (eli PDO on yksi parametrisoituja kyselyjä tukeva vaihtoehto)

Ja täytyy sanoa etten kyllä yhtään tykkää PDOsta. Aloin tekemään yhtä projektia PHP+PDO yhdistelmällä ja vähän päästä totesin että teen sen sittenkin vaikka Javalla+Hibernatella.

eq [13.02.2011 19:35:13]

#

Grez kirjoitti:

Mutta toki PDO on tyhjää parempi, varsinkin kun PHP on oliokieleksi (ja muutenkin) onneton (jälleen IMO).

Ei faktoja tarvitse esittää mielipiteinä...


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta