0

Im fairly new to php/sql, but I did alot of research about this until I decided to get help.

Basically im trying to insert a new username/email/password/salt into a MySQL5 DB. This is my test register.php with just an echo:

include 'dbcxn.php';

$usr = $_POST['user'];
$mail = $_POST['mail'];
$pwd = $_POST['p'];
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
$password = hash('sha512', $pwd.$random_salt);

$insert_stmt = DB::cxn()->prepare("INSERT INTO members (username, email, password, salt) VALUES ($usr, $mail, $password, $random_salt)");
echo $insert_stmt->param_count." parameters\n";

I tried using just "$insert_stmt = $mysqli->prepare", same thing happens. So I made the class DB. Here's my dbcxn.php if it helps:

define("HOST", "");
define("USER", "");
define("PASSWORD", "");
define("DATABASE", "");
define("PORT", "");

$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE, PORT);

class DB {
private static $mysqls;
private function __construct(){}

static function cxn() {
    if( !self::$mysqls ) {
        self::$mysqls = new mysqli(HOST, USER, PASSWORD, DATABASE, PORT);
    }
    return self::$mysqls;
}
}

Don't know what else to try and need to get some sleep :). Thanks in advance for any advice.

  • Where does the error appear exactly? – Pekka Aug 11 '12 at 09:16
  • 1
    Congrats on salting & hashing passwords, but **your code is vulnerable to SQL injection.** You *really* should [parameterise your variables](http://stackoverflow.com/a/60496/623041), so that they do not get evaluated for SQL. If you don't know what I'm talking about, read the story of [Bobby Tables](http://stackoverflow.com/questions/332365/xkcd-sql-injection-please-explain). – eggyal Aug 11 '12 at 09:16
  • thank you, I will study that. – user1591983 Aug 11 '12 at 18:17
  • Correct me if Im wrong, but after using the prepared statament (code below) like its suposed to be used, its no longer vulnerable to injection, right? – user1591983 Aug 11 '12 at 20:20

2 Answers2

1

Your main problem is that your strings are not escaped, at all.

mysqli::prepare() is used for prepared queries. In order to make this work successfully, you should change your query to this:

$insert_stmt = DB::cxn()->prepare("INSERT INTO members (username, email, password, salt) VALUES (?, ?, ?, ?)");
$insert_stmt->bind_param('ssss', $usr, $mail, $password, $random_salt);
$insert_stmt->execute();

You can read up on the bind_param at http://www.php.net/manual/en/mysqli-stmt.bind-param.php for more information, and an explanation on that first parameter ('s' signifying a string value, there are 4 here because you're inserting 4 string values).

Michael
  • 3,151
  • 2
  • 22
  • 27
  • Guess what, didnt get any sleep yet. I figured the SQL syntax error meanwhile, then checked your code and you are absolutely right. I didnt get the prepare/bind_param right at all, but now I do. Thanks! I still have some hashing problems, because I can register but cant login afterwards. But thats another story. Again thanks to both. – user1591983 Aug 11 '12 at 09:41
  • Good that the insert works. For the hash problem, are you sure that both the password and salt columns in your database are wide enough, and that you're doing the same hash algorithm to check the user-supplied password + salt? – Michael Aug 11 '12 at 09:44
  • Nah, it wasnt hash problem after all.. i just had a duplicate email on the database, hence the error. Double hashing is working fine now. I have to work on a "check for existing user" code next :) – user1591983 Aug 11 '12 at 09:51
  • You can add a unique constraint in your mysql database, via: ALTER TABLE `members` ADD UNIQUE(email); – Michael Aug 11 '12 at 09:52
  • works! thanks... so simple. can you recommend any reading on how to interpret and echo SQL errors? such as that one, when someone tries to register the already reg email. – user1591983 Aug 11 '12 at 09:58
  • Start at [mysqli::$error](http://www.php.net/manual/en/mysqli.error.php) and [mysqli_stmt::$error](http://www.php.net/manual/en/mysqli-stmt.error.php). Basically stick to the documentation and work through a couple examples they give you there. – Michael Aug 11 '12 at 10:05
  • Hei Michael, not sure if you're still around. About those error outputs, its working fine for the registration duplicates. But, for the login, it works and outputs error, but it also gives me a warning: "Warning: mysqli::mysqli():" – user1591983 Aug 11 '12 at 18:12
  • It refers to the first line below. I use "$mysqli = new mysqli" for the login and "class DB" wich I didnt paste, for the other connections. $mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE, PORT); if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } – user1591983 Aug 11 '12 at 18:19
0

Your SQL has syntax error. What you get is something like: INSERT INTO members (username, email, password, salt) VALUES (username, test@test.test, mypassword, lkjlk21j3lkjsdclksdmfl3i4)

You may want this:

INSERT INTO members (username, email, password, salt) VALUES (?, ?, ?, ?)

rooobertek
  • 301
  • 1
  • 4