Permalänk

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.

Permalänk
Medlem

Har du ingen databashanterare? Typ phpmyadmin?

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

Visa signatur

[IT-Dept]
Ryzen 1700 OC - 32 - 1070

Permalänk
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?

Permalänk
Medlem
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.

Permalänk
Geeks
Jobbar med data

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.

Permalänk
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; }

Permalänk
Medlem

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.

Visa signatur

X570S AORUS ELITE AX | AMD Ryzen 7 5800X3D | G.Skill 3600C16-16-16 4x8GB TridentZ | Kingston A2000 1TB M.2 NVMe 2st | ASUS GeForce RTX3080 TUF OC | Corsair Hydro H100x | Phanteks Eclipse P400S | Phanteks Revolt Pro 1000W

Permalänk
Geeks
Jobbar med data

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

Permalänk
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å?

Permalänk
Medlem

@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

Permalänk
Geeks
Jobbar med data

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