Olen testaillut ohjelmaa josta oli tuolla https://www.ohjelmointiputka.net/keskustelu/
Testillä minulla on ollut eri sähköpostiosoitteita käyttäjätunnuksena.
Näyttäisi siltä, että moitiskelee ainakin paria sähköpostia.
$sala = string_crypt(trim($_POST['salasana']),mykey(),"encrypt"); $sm = string_crypt(trim($_POST['myusername']),mykey(),"encrypt"); $_POST['myusername'] = trim($_POST['myusername']); $result = mysql_query("SELECT * FROM Rekisteri WHERE tunnus='".$_POST['myusername']."' OR sahkoposti='$sm") or die ("Odottamaton virhe: ".mysql_error());
Tämän testi-osoitteen kodalla tulostaa tällaisen virheen:
Odottamaton virhe: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''�V�\'cQ��}V-�2|���x��d^O' at line 1
Olen testannut, että kannassa oleva salaus vastaa täysin sitä, mitä on tuossa muuttujassa $sm.
Lisäksi kerran se tallensi salauksen kantaa väärässä muodossa. Kun poistin rivin ja tallensin uudestaan kantaan, tallentui oikein. Sähköposti oli tuossa ihan oikein kirjoitettu, koska se lähetti aktivointi-viestin kyseiseen sähköpostiin.
Ps. Testasin tuossa myös funktiota mysql_real_escape_string. Silloin ei herjaa mitään, mutta moitti että virheellinen tunnus tai salasana, vaikka kaikki "täsmää".
Sun pitää ajaa syötteet mysql_real_escape_string-funktion läpi tai käyttää PDO:ta. Kyselystä tulee nyt jotenkuten tämmöinen...
SELECT * FROM Rekisteri WHERE tunnus=''�V�\'cQ��}V-�2|���x��d^O ...
Muokkaus. Tai sitten se johtuu vasta myöhemmästä vaiheesta, jossa sulta puuttuu heittomerkki $sm-muuttujan perästä.
Jos $sm-muuttujan arvo olisi ; drop table Rekisteri
, niin Rekisteri-taulu poistettaisiin.
Muokkaus 2. Nähtävästi sanoitkin kokeilleesi jo mysql_real_escape_string-funktiota. Älä ota sitä pois, se varmistaa ettei käyttäjä tee edellä mainitsemaani SQL-injektiota.
Katos vaan. Niimpä puuttuukin. Kumma että on hyväksynyt monen testi-tunnuksen laittamisen. No testit jatkuu......
Laitoitko sen mysql_real_escape_stringin edes oikeaan väliin? Kai ne kentät ovat nyt binaarityyppisiä eivätkä tekstityyppisiä? Kannattaisi myös siirtyä MySQL-funktioista PDO:hon, niin ei tarvitsisi escapettaa eikä tulisi tuollaisia heittomerkkivirheitä. Helppoa kuin mikä:
$kysely = $pdo->prepare("SELECT * FROM Rekisteri WHERE tunnus = ? OR sahkoposti = ?"); $kysely->execute($_POST["myusername"], $sm);
Herjat loppui.
"Virheellinen tunnus tai salasana!"
Ja kaiken järjen mukaan ne on ihan samat...
Kentät on minulla varbinary, pitäisikö olla pelkkä binary? Toisaalta se salaus on kannassa sama kuin tuossa muuttujassa $sm, ei silmin nähtävää eroavuutta. Jos eroa on se on jotain mitä ihmissilmä ei voi nähdä.
Joo.. tuo PDO voisi olla hyvä juttu, ei ole tullut käytettyä. Mutta tuo rakenne on minulle Perlistä tuttua.
Ps. Kun hommat on salatussa muodossa niin laitetaan tänne. Kuka löytää näistä jotain eroa:
Tunnus: f4561b276351b0dd7d562d06327c16d2e2bb7889f5645e4f f4561b276351b0dd7d562d06327c16d2e2bb7889f5645e4f Salasana: db1437c5b531b7d8 db1437c5b531b7d8
Mutta mutta.... näyttää siltä että homma hoituu kohta. Tämän testi-sähköpostin kanssa pitänee käyttää mysql_real_esacpe_string - funktiota mysö kannassa olevalle salaukselle...
Olet kyllä tähänkin asti ollut sellainen koheltaja, että täytyy nyt kysyä ihan yksinkertaista asiaa: tulostitko varmasti samat muuttujat, joita tungit kyselyyn, ja lukevatko kyselyssä varmasti samat kentät, jotka tarkistit tietokannasta? Tuossa ylempänä laitat kyselyyn ilmeisesti salaamattoman tunnuksen ja salatun tunnuksen, ja taulusta haet tunnusta ja sähköpostia.
(Entä miten teit tulostuksen, kun tuli pelkkää heksaa?)
Metabolix kirjoitti:
Tuossa ylempänä laitat kyselyyn ilmeisesti salaamattoman tunnuksen ja salatun tunnuksen, ja taulusta haet tunnusta ja sähköpostia.
(Entä miten teit tulostuksen, kun tuli pelkkää heksaa?)
Taulusta haetaan tunnus(luotu nimimerkki) tai sähköposti, molemmat käy käyttäjätunnuksina.
Näinpä testailin onko sama vai ei
echo 'Tunnus:<br>'; echo 'f4561b276351b0dd7d562d06327c16d2e2bb7889f5645e4f'; # kannassa echo '<br>'; echo bin2hex($sm); echo '<br>'; echo 'Salasana:<br>'; echo 'db1437c5b531b7d8'; # kannassa echo '<br>'; echo bin2hex($sala);
Ja kuten ylhäältä käy ilmi, noi muuttujat tulee POST-lomakkeelta.
Mutta eipä auttanu vielä vaikka muutin tuon mysql-real-esacpe-stringin $rouwille.
Mutta print_r($row) kuitenkin tulostaa arrayn.
Joten mennään if-lauseeseen:
$row['sahkoposti'] == mysql_real_escape_string($row['sahkoposti']); $row['salasana'] == mysql_real_escape_string($row['salasana']); if($row['tunnus'] == $_POST['myusername'] && $row['salasana'] == $sala or $row['sahkoposti'] == $sm && $row['salasana'] == $sala){ }
Tätä se nyt ei näyttäisi tunnistavan...
Mistä nuo "kannassa" olevat eli käsin laitetut arvot ovat oikeasti peräisin? Mitä jos vielä tulostaisit vielä nuo $row-taulukon kohdat, joita if-lauseessa käytät?
Ja escapetus ei todellakaan kuulu tuohon väliin, onko asian idea ihan kokonaan hukassa? O_o Sitä paitsi == on vertailu eikä sijoitus.
Tuossa tapahtuu matkan varrella muunnos:
Tulostus ennen mysql-real-escape-stringiä Tunnus: f4561b276351b0dd7d562d06327c16d2e2bb7889f5645e4f < phpmyadmin f4561b276351b0dd7d562d06327c16d2e2bb7889f5645e4f < lomake Salasana: db1437c5b531b7d8 db1437c5b531b7d8 Tulostus stringin ja $row-muuttujan jälkeen: Tunnus: f4561b276351b0dd7d562d06327c16d2e2bb7889f5645e4f < phpmyadmin f4561b5c276351b0dd7d562d06327c16d2e2bb7889f5645e4f < lomakkeelta f4561b276351b0dd7d562d06327c16d2e2bb7889f5645e4f < tulostus kannasta Salasana: db1437c5b531b7d8 db1437c5b531b7d8
Ps. Sain homman pelaamaan. Asetin alkuperäisen lomaketiedon eri muuttujaan talteen.
$sp = $sm; $sm = mysql_real_escape_string($sm); $sala = mysql_real_escape_string($sala); # ---- if($row['tunnus'] == $_POST['myusername'] && $row['salasana'] == $sala or $row['sahkoposti'] == $sp && $row['salasana'] == $sala){ # Löytyy }
Sitäkin voi ihan loogisesti miettiä, olisiko mysql_real_escape_string-funktiosta mitään hyötyä, jos se ei koskaan muuttaisi arvoa mitenkään.
Toivottavasti opit tästä, että ne debug-tulosteet kirjoitetaan ongelmakohdan viereen eikä johonkin toiselle laidalle skriptiä. Jos on yllättävä poikkeama, siirretään tulostetta taaksepäin, kunnes muutoskohta löytyy.
Aihe on jo aika vanha, joten et voi enää vastata siihen.