Trädvy Permalänk
Medlem
Plats
Örebro
Registrerad
Jul 2007

Problem med mysqli insert

Är supertacksam om någon kunde hitta felet i min mysqli-insert:

$secret = mksecret(); $wantpasshash = md5($secret . $wantpassword . $secret); $editsecret = (!$arr[0]?"":mksecret()); $ret = mysqli_query($mysqli, "INSERT INTO users (username, passhash, secret, editsecret, email, status, ". (!$arr[0]?"class, ":"") ."added) VALUES (" . implode(",", array_map("sqlesc", array($wantusername, $wantpasshash, $secret, $editsecret, $email, (!$arr[0]?'confirmed':'pending')))). ", ". (!$arr[0]?UC_SYSOP.", ":""). "'". get_date_time() ."')"); if (!$ret) { if (mysqli_errno($mysqli) == 1062) error("Användarnamnet finns redan!"); bark("Ooops"); }

Inget sparas i databasen, och det enda jag får upp hela tiden är "Ooops".
Är jag totalt blind? Har suttit med detta ett tag nu.

Trädvy Permalänk
Medlem
Plats
Stockhom
Registrerad
Jun 2004

Har du ingen databashanterare? Typ phpmyadmin?

Då kan du köra frågorna rakt i denna & se var det felar.

Main: Ryzen 7 - 1700 @ 3.9 | 32 Gb Corsair 3000 MHz | RX 590 8Gb
Backup: NAS - Synology
--------------------------------------------------
Grundare av MaseApps. Se våra spel: www.maseapps.com. För IOS och Android.

Trädvy Permalänk
Medlem
Plats
Örebro
Registrerad
Jul 2007
Skrivet av iXam:

Skriv ut vad

"INSERT INTO users (username, passhash, secret, editsecret, email, status, ". (!$arr[0]?"class, ":"") ."added) VALUES (" . implode(",", array_map("sqlesc", array($wantusername, $wantpasshash, $secret, $editsecret, $email, (!$arr[0]?'confirmed':'pending')))). ", ". (!$arr[0]?UC_SYSOP.", ":""). "'". get_date_time() ."')"

blir med print (som koden du tagit från gör https://github.com/CptTZ/NexusPHP/blob/master/activate.php ). Stoppa in den manuellt i databasen (shell eller gui) och se vad du får för felmeddelande om du inte ser direkt vad som är felet.

Och använd inte MD5.

Allt skrivs ut som det ska med print, så felet är inte där.

INSERT INTO users (username, passhash, secret, editsecret, email, status, added) VALUES ('test','7c369221d162fb61421a2d4b05177c4b','ön�k4\n$���/�i��lJ�','�����:\Zް� H �e���','test@testdoman.se','pending', '2020-07-13 10:04:42')

..och vad ska jag använda istället för MD5?

Trädvy Permalänk
Medlem
Plats
Örebro
Registrerad
Okt 2001
Skrivet av Guldstrand:

..och vad ska jag använda istället för MD5?

Bcrypt borde fungera, vad det finns för implementationer för detta i PHP vet jag dock inte.

Trädvy Permalänk
Jobbar med data
aka Takida
Plats
Stockholm
Registrerad
Nov 2011

Anledningen till att du inte kan spara informationen i databasen är att din secret (och editsecret) består av binär data, vilket har en tendens att bryta sig loss om de inte escapas korrekt.

Det här fenomenet (att inte escapa din data) leder även till att du är utsatt för något som heter SQL Injections, och löser sig lättast med MySQLi Prepared Statements.

Nu vet jag inte vad din editsecret ska göra för något, så kan inte svara på att din mksecret() gör det på ett säkert sätt. Däremot är din hantering av lösenord livsfarlig. Du kan använda dig utav password_hash, den genererar en dynamisk salt och lagrar ditt lösenord på ett kryptologiskt säkert sätt. MD5 är idag gammal och skall under inga omständigheter användas.

Trädvy Permalänk
Medlem
Plats
Örebro
Registrerad
Jul 2007
Skrivet av jreklund:

Anledningen till att du inte kan spara informationen i databasen är att din secret (och editsecret) består av binär data, vilket har en tendens att bryta sig loss om de inte escapas korrekt.

Nu vet jag inte vad din editsecret ska göra för något, så kan inte svara på att din mksecret() gör det på ett säkert sätt.

Stort tack för ett bra svar, utan en massa kritik och påhopp.

Kan du förklara ytterligare vad du menar?
Vill gärna försöka använda den koden jag har. (är fortfarande ganska novis)

function mksecret($len = 20) { $ret = ""; for ($i = 0; $i < $len; $i++) $ret .= chr(mt_rand(0, 255)); return $ret; }

Trädvy Permalänk
Medlem
Registrerad
Sep 2011

Bcrypt i PHP är simpelt. Man använder bara https://www.php.net/manual/en/function.password-verify.php och https://www.php.net/manual/en/function.password-hash.php när man genererar hashen.

Normalt så sparar man inte data in en database i binär form. Om du nu måste så kan du använda Base64 enkodning för att få det till textformat.

MSI Z490 MPG GAMING EDGE WIFI | i7 10700K @ 5.2 GHz | G.Skill 3600C16-16-16 4x8GB TridentZ | Kingston A2000 1TB M.2 NVMe | ASUS GeForce RTX2080 SUPER ROG Strix OC 8G Gaming | Corsair Hydro H100x | Phanteks Eclipse P400S | Corsair RM 750x

Trädvy Permalänk
Jobbar med data
aka Takida
Plats
Stockholm
Registrerad
Nov 2011

@Guldstrand Den funktionen skulle jag byta ut mot random_bytes, då den kommer förr eller senare att krocka (inte kryptologisk säker). Kör du mksecret() ett par gånger, så kommer du att få samma resultat, då tecknet du genererar med mt_rand inte är säker.

Vilket leder till att några av dina användare kommer att få samma "secret", vad du nu använder den till. Den kommer alltså inte vara unik.

Du kan byta ut den rakt av eller ersätta innehållet i mksecret (så att den bara kallar på random_bytes), för att få bakåtkompatibilitet.

function mksecret($len = 20) { return random_bytes($len); }

@Akandesh Det går utmärkt att spara information i binär form, och är även snabbare om du t.ex. sparar en UUIDv4 sträng och ska göra joins på den. Binär data går fortare att slå på än textsträngar och tar mindre plats än om du ska base64 encoda allting.

Trädvy Permalänk
Medlem
Plats
Örebro
Registrerad
Jul 2007
Skrivet av jreklund:

@Guldstrand Den funktionen skulle jag byta ut mot random_bytes, då den kommer förr eller senare att krocka (inte kryptologisk säker). Kör du mksecret() ett par gånger, så kommer du att få samma resultat, då tecknet du genererar med mt_rand inte är säker.

Vilket leder till att några av dina användare kommer att få samma "secret", vad du nu använder den till. Den kommer alltså inte vara unik.

Du kan byta ut den rakt av eller ersätta innehållet i mksecret (så att den bara kallar på random_bytes), för att få bakåtkompatibilitet.

function mksecret($len = 20) { return random_bytes($len); }

Stort tack för hjälpen!
Jag bytte till din funktion istället.

Men vad är felet med att inget sparas i databasen då?

Trädvy Permalänk
Medlem
Registrerad
Apr 2020

@Guldstrand: Jag kanske också är blind men var är databaskopplingen?
Vad gäller hash brukar jag köra med password_hash($password, PASSWORD_DEFAULT);

Sedan så är PDO och prepared statements att föredra framför mysqli

Trädvy Permalänk
Jobbar med data
aka Takida
Plats
Stockholm
Registrerad
Nov 2011

@Guldstrand Min kvalificerade gissning är att det du försöker spara i form av binär data bryter sig loss från strängen och dödar SQL-satsen. Nu kan jag inte se ' och , i detta fall, men de strängarna brukar kunna innehålla den informationen och döda den. Därav var min rekommendation att gå över till MySQLi Prepared Statement. Då skyddas du även mot SQL Injections.

Du kan ju alltid köra mysqli error löst, för att se vilken error kod du får och Googla problemet

mysqli_errno($mysqli);