Eli täälläinen virhe tulee rivillä 40. Koodi on tämä:
<?php include("fun.php"); yhdista(); if (isset($_GET['id']) && $_GET['id'] == "reg") { $sql = "select tunnus from lataamo_users where tunnus = '$_POST[tunnus]'"; $mysql = mysql_query($sql); $rivi = mysql_fetch_assoc($mysql); if ($rivi) { echo "Sama tunnus on jo käytössä!"; } else { if ($_POST['tarkistus'] == $_GET['tar']." " or $_POST['tarkistus'] == $_GET['tar']) { if ($_POST['tunnus'] and $_POST['salasana1'] and $_POST['salasana2'] and $_POST['email']) { if ($_POST['salasana1'] == $_POST['salasana2']) { $salasana = sha1($_POST['salasana1']); $sql = "insert into lataamo_users (id,tunnus,password,email) values (0,'$_POST[tunnus]','$salasana','$_POST[email]')"; $mysql = mysql_query($sql); } else { echo "Salasanat eivät täsmää!"; } } else { echo "Jätit jonkun kohdan tyhjäksi";} } else { echo "Varmistus koodi ei ole oikein!"; } } } elseif (isset($_GET['id']) && $_GET['id'] == "log") { include("session.php"); if (!$_POST['tunnus'] and !$_POST['salasana']) { echo "Et kirjoittanut tunnusta tai salasanaa!"; } else { $salasana = sha1($_POST['salasana']); $sql = "select tunnus from lataamo_users where tunnus = $_POST[tunnus] and password = $salasana"; $mysql = mysql_query($sql); $rivi = mysql_fetch_assoc($mysql); if ($rivi['tunnus']) { $_SESSION['tunnus'] = $_POST['tunnus']; header("Location:testi.php"); } else { echo "Salasana ja tunnus eivät täsmää!"; } } } else { echo "Virhe!Virhe!"; } ?>
(Mod. lyhensi otsikon kohtuulliseen mittaan.)
Ensin täytyy kysyy, että toimiiko tuo yhdista()-funktio? Sen lisäksi noille mysql_query-funktiolle kannattaisi antaa resurssi-muuttuja toiseksi parametriksi. Sen lisäksi tuossa koodissa on aika pahoja injektioaukkoja...
Yhdista funktio on fun.php:eessä ja se toimii. Mitä tarkoitat tuolla resurssi - muuttuja? Se muuttuja missä on yhdistäminen mysql:ään vai? On noi ennen toiminut mutta nyt tömähti koko pask*.
1. Sisennä järkevästi.
2. Tulosta kysely ennen kantaan ajamista, jolloin löydät virheen itsekin
Virhe sanoo aivan selvästi, että kantaan ajettu kysely ei ole kelvollinen.
/* Muotoilen kyselyitä */ SELECT tunnus FROM lataamo_users WHERE tunnus = $_POST[tunnus] /* !!! */ AND password = $salasana"; /* !!! */ INSERT INTO lataamo_users (id,tunnus,password,email) VALUES (0, /* !!! */ '$_POST[tunnus]', '$salasana', '$_POST[email]') SELECT tunnus FROM lataamo_users WHERE tunnus = '$_POST[tunnus]' /* !!! */
Taas noita pikku virheitä ;). Eli olin unohtanut laittaa heittomerkin ennen muuttujaa ja sen jälkeen
Kuten jo edellä vihjattiin, sijoitat käyttäjältä saadun merkkijonon sellaisenaan sql-lauseeseen, mikä on eräs pahimmista mahdollisista tietoturva-aukoista.
Lisätietoa esim. http://wiki.mureakuha.com/wiki/SQL-injektio
Ja kaikilla käyttäjillä on id 0?
alker kirjoitti:
Taas noita pikku virheitä ;). Eli olin unohtanut laittaa heittomerkin ennen muuttujaa ja sen jälkeen
Ei ei virheitä on paljon lisää tuossa koodissa. Toivon totisesti, että tämä ei ole millään julkisella palvelimella. Chiman vinkkasikin jo erittäin hyvään oppaaseen. Lue esimerkiksi rivi 13, josta ei ihan heti selviä, että miksi tuossa kysellään totuusarvoa muuttujista, jotka eivät nyt ainakaan nimiensä puolesta sisällä true / false arvoa. empty(mixed) saattaisi olla trim(string) funktiolla höystettynä se mitä haet, mutta tuota koodia tulisi siistiä niin monelta kohdalta, että taitaa olla parempi, että kirjoitat sen ihan uusiksi ajatuksen kanssa.
Olen laittanut sen id-jutun niin että se on primary key ja auto_increment. ELi en laita jokaiselle tunnukselle id:eetä 0. Mitäs minä sitä muka muokkailen jos se tekee asiansa? Se menee yksityiseen käyttöön ei mihinkään miljoonien ladattavaksi
alker kirjoitti:
Olen laittanut sen id-jutun niin että se on primary key ja auto_increment. ELi en laita jokaiselle tunnukselle id:eetä 0.
Silloin ei kannata laittaa tuota kenttää INSERT lauseeseen ollenkaan sekoittaa vaan suotta.
Joo, MySQL:llä taitaa sentään mennä läpi. Jotkut kannathan antaa suoraan virheen, jos yrittää jotain työntää itse auto_incrementtiin.
Ja mitä minä tuolla SQL -inhektiolla kun salasana on hassattu tietokantaan?
Eihän tuolla periaatteessa olekaan mitään väliä jos tunnuksella, jolla kantaa käytetään, on vain select oikeus sellaisiin tauluihin, joissa on vain täysin julkista dataa.
En ole ihan varma tämän toimivuudesta, koska moinen ei kuulu harrastuksiin, mutta jos laitoit tuohon jo heittomerkit:
$sql = "select tunnus from lataamo_users where tunnus = '$_POST[tunnus]' and password = '$salasana'";
niin kokeilepa vaikka kirjautua tunnuksella: ' OR 1 OR 'a'='a
Salasanaksi laita mitä tahansa, kunhan jotain.
Chiman kirjoitti:
En ole ihan varma tämän toimivuudesta, koska moinen ei kuulu harrastuksiin, mutta jos laitoit tuohon jo heittomerkit:
$sql = "select tunnus from lataamo_users where tunnus = '$_POST[tunnus]' and password = '$salasana'";niin kokeilepa vaikka kirjautua tunnuksella: ' OR 1 OR 'a'='a
Salasanaksi laita mitä tahansa, kunhan jotain.
Ei toimi koska se hassaa salasanan ennenkuin se tarkistaa sen MYSQL:ästä
Chiman kirjoitti:
niin kokeilepa vaikka kirjautua tunnuksella: ' OR 1 OR 'a'='a
Salasanaksi laita mitä tahansa, kunhan jotain.
Toimii minusta juuri niin, että valitsee kaikki kannassa olevat tunnukset. Että mitäs sinä huolehdit onhan salasana salattu...
alker kirjoitti:
Yhdista funktio on fun.php:eessä ja se toimii. Mitä tarkoitat tuolla resurssi - muuttuja? Se muuttuja missä on yhdistäminen mysql:ään vai? On noi ennen toiminut mutta nyt tömähti koko pask*.
Tosiaan se resurssimuuttuja on se, mikä viittaa siihen tietokantayhteyteen... Toiseksi kannattaisi alkaa käyttää hieman selkeempiä muuttujien nimiä, jo ihan selkeyden vuoksi.
alker kirjoitti:
Ei toimi koska se hassaa salasanan ennenkuin se tarkistaa sen MYSQL:ästä
Kokeilitko? Jos se toimii kuten ajattelin, ei salasanalla ole väliä, koska yksi OR-ehdoista toteutuu.
Chiman kirjoitti:
Kokeilitko? Jos se toimii kuten ajattelin, ei salasanalla ole väliä, koska yksi OR-ehdoista toteutuu.
Ei se kokeillut, koska tuo toimii täsmälleen, kuten sanoin. Valitsee siis kaikki kannassa olevat tunnukset. Salasanalla ei ole väliä, koska kuten Chiman sanoin toteutuu OR ehto ja AND jää virattomaksi.
Aihe on jo aika vanha, joten et voi enää vastata siihen.