Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: MySql SQL syntax error

Sivun loppuun

pistemies [31.07.2011 22:00:20]

#

Olen testaillut ohjelmaa josta oli tuolla https://www.ohjelmointiputka.net/keskustelu/22794-mcrypt-funktion-sisällä

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ää".

Macro [31.07.2011 22:02:18]

#

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.

pistemies [31.07.2011 22:07:15]

#

Katos vaan. Niimpä puuttuukin. Kumma että on hyväksynyt monen testi-tunnuksen laittamisen. No testit jatkuu......

Metabolix [31.07.2011 22:08:28]

#

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);

pistemies [31.07.2011 22:19:49]

#

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...

Metabolix [31.07.2011 22:35:01]

#

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?)

pistemies [31.07.2011 22:47:48]

#

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...

Metabolix [31.07.2011 22:53:00]

#

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.

pistemies [01.08.2011 00:12:23]

#

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
}

Metabolix [01.08.2011 01:30:06]

#

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.


Sivun alkuun

Vastaus

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

Tietoa sivustosta