Hei,
Ajan ohjelmassa kaikki stringit alla olevan funktion läpi, jotka tallenetaan kantaan.
Kannattaisko tohon vielä lisätä jotain injektioiden estämiseksi? Vai riittääkö noin.
function validate_string($s_string) { return mysql_real_escape_string($s_string); }
Mod. lisäsi kooditagit!
Itse nimeäisin funktion niin, että nimi vastaa sitä mitä funktio tekee. Eli ennemmin vaikka escape_string kuin validate_string.
Jotta tuohon voisi lisätä jotain hyödyllistä injektioiden estämiseksi, niin pitäisi tietää minkälaisia injektioita mysql_real_escape_string ei torju. Itselläni ei ole sellaista tiedossa, joten en osaa suositella mitään lisäystä.
Hmm, muutin sitä nyt seuraavaksi, kun googlettelin tossa funktioita.. siellä oli jokin missä oli escapen lisäksi htmlspecialchars, se nyt ei varsinaisesti injektioita torju.. mutta kaipa se on hyvä olla lisänä
function escape_string($str_string) { $str_string = htmlspecialchars($str_string); return mysql_real_escape_string($str_string); }
Mod. lisäsi kooditagit!
Et siis varmaankaan käytä PDO:ta. PDO:han käsittelee kaiken automaattisesti.
Itse käytän PDO:ta. Testasin eilen MySql:lää PHP:n ja PDO:n kanssa (latasin koneelleni XAMPP:in viikko sitten).
EDIT: Meinasin ensiksi käyttää tuota MySql -laajennosta mutta en sattunut lyhyessä ajassa löytämään mitään erityisen hyvää vinkkiä siihen. Siksi päädyin PDO:hon.
ErroR++:n lisäksi myös PHP:n tekijät suosittelevät PDO:n laajennuksen käyttöä mieluummin:
"PHP:n tekijät: Älkää käyttäkö mysql-laajennustamme!"
http://www.tietoviikko.fi/kehittaja/phpn tekijat alkaa kayttako mysqllaajennustamme/a656999
Tekstit kannattaa tallentaa tietokantataan sellaisenaan ja ajaa htmlspecialchars-funktion läpi vasta tulostusvaiheessa, koska niitä on silloin huomattavasti helpompi käsitellä.
eppu55 kirjoitti:
Ajan ohjelmassa kaikki stringit alla olevan funktion läpi, jotka tallenetaan kantaan.
Kannattaisko tohon vielä lisätä jotain injektioiden estämiseksi? Vai riittääkö noin.function validate_string($s_string) { return mysql_real_escape_string($s_string); }
==
mysql_real_escape_string($s_string);
... Miksi kääriä funktio funktioon? Hämmentääkseen sen toiminnallisuutta.? Eihän mysql_real_escape_string -funktio suorita minkäänlaista validointia..
Eihän injektioiden vaaraa ole ainoastaan "stringeissä jotka tallenetaan kantaan.", vaan kaikissa kyselyissä johon käyttäjä pääsee vaikuttamaan syötteillä.. Oletko ymmärtänyt asian ihan oikein?
"Et siis varmaankaan käytä PDO:ta."
En käytä..
"Tekstit kannattaa tallentaa tietokantataan sellaisenaan ja ajaa htmlspecialchars-funktion läpi vasta tulostusvaiheessa, koska niitä on silloin huomattavasti helpompi käsitellä."
Ihan hyvä huomio, saatan tehdäkin sen noin päin mielummin.
"Miksi kääriä funktio funktioon? Hämmentääkseen sen toiminnallisuutta.?"
Siks että.. jos siihen tulisi muita funktioita vielä ympärille, niin olisi sitten kaikki yhden funktion sisällä, mutta eipä tohon näillä näkymin ole tulossa jos jätän ton specialcharsinkin pois
Mitähän varten PHP:hen olisi keksitty funktio "tee stringistä MySQL-turvallinen", jos se ei tekisikään siitä "MySQL-turvallista"? (Tosin se kutsuu vain MySQL:n oman kirjaston funktiota, joten varsinaisesti ei edes ole PHP:n oma funktio.)
Jos muuttujan on tarkoitus olla luku (ja siis SQL-lauseessa ei ole lainausmerkkejä sen ympärillä), escape ei auta vaan kannattaa käyttää yksinkertaisesti funktiota intval (tai floatval).
En kyllä keksi, miten mysql_real_escape_string():n läpi ajettu stringi aiheuttaisi ilman hipsuihin käärimistäkään mitään ongelmia. Kyselyhän luonnollisesti heittää syntax erroria, mutta onko sitten tarkoituksenmukaista laittaa kantaan mitä tahansa roskaa, mitä joku idiootti keksiikään lähetellä?
Vertailun vuoksi voidaan ihmetellä PDO:ta. Sekään ei bindValue:ta käyttäessä castaa muuttujaa intiksi, vaikka arvon tyypiksi eksplisiittisesti määräisi PDO::PARAM_INT.
The Alchemist kirjoitti:
En kyllä keksi, miten mysql_real_escape_string():n läpi ajettu stringi aiheuttaisi ilman hipsuihin käärimistäkään mitään ongelmia.
Jaa, että se ei haittaa jos käyttäjä tekee sivupyynnön:
oppilaitos.edu/kurssit/1 AND Id=0 UNION SELECT Id, Username, Email, Password FROM Students
Ja tietokannalle ajetaan kysely:
SELECT Id, Header, Description, Footer FROM Course WHERE Id=1 AND Id=0 UNION SELECT Id, Username, Email, Password FROM Students
Periaatteessa en näe injektion torjumisen kannalta mitään hyötyä ajaa mysql_real_escape_string(), jos sen tuotosta ei laiteta hipsujen sisään.
The Alchemist kirjoitti:
Vertailun vuoksi voidaan ihmetellä PDO:ta. Sekään ei bindValue:ta käyttäessä castaa muuttujaa intiksi,
Jotain muuta siellä selvästikin silti tapahtuu, kun esim. "SELECT ?" palauttaa arvon muuttumattomana ja "WHERE id = ?" onnistuu tulkitsemaan tekstin "1 heippa" luvuksi 1 ilman syntaksivirhettä.
Käsittelemättömän luvun vaaroja Grez jo hienosti demonstroikin. Lisäisin tuohon vielä, että hyvinkin pieni aukko riittää minkä tahansa tiedon hakemiseen: Hakkeri voi syöttää luvun X tilalle lähes mielivaltaisen alikyselyn, joka onnistuessaan tuottaa luvun X ja epäonnistuessaan jotain muuta. Tulostuvasta sivusta näkee, onnistuiko kysely, eli mihin tahansa kyllä–ei-kysymykseen saadaan vastaus. Varsinaisia tietoja voi sitten hakea vaikka binaarihaulla. Koodasin kerran jopa skriptin tätä varten – proof-of-concept-mielessä tietenkin. (Grezin esittämä suora UNION on totta kai tehokkaampi, mutta sellaisen upottaminen tuntemattomaan kyselyyn voi joskus olla hankalaa.)
Aihe on jo aika vanha, joten et voi enää vastata siihen.