I'm currently working on the login system on my site. Each user recieves a unique key on purchase that they then use to register on the site. Upon registration with the key it gets passed through a script that checks my database of keys to make sure it isn't in use already (if it passes that check, the key is marked "in use"). It then moves on to insert the user in the database, storing their key as well as their payment status as "sub".
My issue is that my script is completely ignoring the key check if/else block. It fails to change the in_use to "Y". It is also telling me registration successful even though the pay_status variable is not being passed to the final insert statement.
Was wondering if anyone could have a go at my php and see if there is anything obvious I am missing. Ignore the injectable points as I stripped the code down to get it functioning before I secure it again.
Heres the php:
<?php
include_once 'link_auth.php';
include_once 'link_global.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'], $_POST['firstname'], $_POST['lastname'], $_POST['regkey'])) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$firstname = filter_input(INPUT_POST, 'firstname', FILTER_SANITIZE_STRING);
$lastname = filter_input(INPUT_POST, 'lastname', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
$regkey = $_POST['regkey'];
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
//Check if the registration key is in use --> If so, close statement, if not, mark key as in_use = Y and add it to the user's account, set payment status from trial (if trial) to sub
$prep_stmt = "SELECT id, regkey, in_use FROM keylist WHERE regkey = '$regkey' LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->execute();
$keystatus = $stmt->fetch();
if ($keystatus['in_use'] == 'N') {
//The key is available
$sql_updatekey = "UPDATE `keylist` SET in_use = 'Y' WHERE `regkey` = '$regkey'";
$pay_status = "sub";
$mysqli->query($sql_updatekey);
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">This key is already in use. If you feel this is an error, please contact support#hospitaldatasolutions.com</p>';
$stmt->close();
}
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error">A user with this username already exists</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
$stmt->close();
}
// TODO:
// We'll also have to account for the situation where the user doesn't have
// rights to do registration, by checking what type of user is attempting to
// perform the operation.
if (empty($error_msg)) {
// Create a random salt
//$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); // Did not work
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password
$password = hash('sha512', $password . $random_salt);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, firstname, lastname, regkey, salt, payment_status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssssssss', $username, $email, $password, $firstname, $lastname, $regkey, $random_salt, $pay_status);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
}
}
header('Location: register_success.php');
}
}
EDIT: Here is the correct result:
//Check if the registration key is in use --> If so, close statement, if not, mark key as in_use = Y and add it to the user's account, set payment status from trial (if trial) to sub
$prep_stmt = "SELECT regkey, active FROM keylist WHERE regkey = '$regkey' LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($col2,$col3);
$keystatus = $stmt->fetch();
var_dump($col2,$col3);
if ($keystatus && $col3=='N') {
//The key is available
$sql_updatekey = "UPDATE `keylist` SET active = 'Y' WHERE `regkey` = '$col2'";
$res=$mysqli->query($sql_updatekey);
$stmt->close();
}
else {
$error_msg .= '<p class="error">This key is already in use. If you feel this is an error, please contact support#hospitaldatasolutions.com</p>';
$stmt->close();
}
}
The store_result() method is key as it frees up $mysqli to perform a new query. If there are still results waiting from the previous query, it will fail to perform the next. As of now my problem is completely solved. Both tables update with the necessary information.
There is logical error in if else part, I think els block for "key already used" is misplaced with if($stmt). I assume your Keylist has in_use = 'N' for not used keys.
<?php
include_once 'link_auth.php';
include_once 'link_global.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'], $_POST['firstname'], $_POST['lastname'], $_POST['regkey'])) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$firstname = filter_input(INPUT_POST, 'firstname', FILTER_SANITIZE_STRING);
$lastname = filter_input(INPUT_POST, 'lastname', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
$regkey = $_POST['regkey'];
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
//Check if the registration key is in use --> If so, close statement, if not, mark key as in_use = Y and add it to the user's account, set payment status from trial (if trial) to sub
$prep_stmt = "SELECT id, regkey, in_use FROM keylist WHERE regkey = '$regkey' LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->execute();
$stmt->bind_result($col1, $col2,$col3);
$keystatus = $stmt->fetch();
if ($keystatus && $col3=="N") {
//The key is available
$sql_updatekey = "UPDATE `keylist` SET in_use = 'Y' WHERE `regkey` = '$regkey'";
$pay_status = "sub";
$mysqli->query($sql_updatekey);
$stmt->close();
}
else {
$error_msg .= '<p class="error">This key is already in use. If you feel this is an error, please contact support#hospitaldatasolutions.com</p>';
$stmt->close();
}
}
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error">A user with this username already exists</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
$stmt->close();
}
// TODO:
// We'll also have to account for the situation where the user doesn't have
// rights to do registration, by checking what type of user is attempting to
// perform the operation.
if (empty($error_msg)) {
// Create a random salt
//$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); // Did not work
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password
$password = hash('sha512', $password . $random_salt);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, firstname, lastname, regkey, salt, payment_status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssssssss', $username, $email, $password, $firstname, $lastname, $regkey, $random_salt, $pay_status);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
}
}
header('Location: register_success.php');
}
}
Related
I am trying to create a registration form (using an SQL database) that utilizes my
"register.inc.php" file, When I attempt to create an account (as a test) I get
THIS error:
"Fatal error: Call to a member function prepare() on null in /usr/www/world/includes/register.inc.php on line 30"
I've posted the code from my register.inc.php, any insight would be much appreciated.
<?php
include_once 'loginhandler.php';
include_once 'DBclass.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'])) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
$stmt->close();
}
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error">A user with this username already exists</p>';
$stmt->close();
}
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
$stmt->close();
}
// TODO:
// We'll also have to account for the situation where the user doesn't have
// rights to do registration, by checking what type of user is attempting to
// perform the operation.
if (empty($error_msg)) {
// Create hashed password using the password_hash function.
// This function salts it with a random salt and can be verified with
// the password_verify function.
$password = password_hash($password, PASSWORD_BCRYPT);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password) VALUES (?, ?, ?)")) {
$insert_stmt->bind_param('sss', $username, $email, $password);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
}
}
header('Location: ./register_success.php');
}
}
?>
I'm thinking that 'DBclass.php' contains an assignment to "$ mysqli" variable. It's correct? Because in your current script it does not contain any assigment to this variable. (So it's OK, it contains null value because it's never initialized)
Here is the register.inc.php
<?php
include_once 'db_connect.php';
include_once 'psl-config.php';
include_once 'functions.php';
$error_msg = "";
sec_session_start();
if (isset($_POST['username'], $_POST['email'], $_POST['p'], $_POST['firstname'], $_POST['lastname'], $_POST['email'], $_POST['contactno'], $_POST['address'], $_POST['inviteid']
)) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
$phone = filter_input(INPUT_POST,'contactno', FILTER_SANITIZE_STRING);
$firstname = filter_input(INPUT_POST, 'firstname', FILTER_SANITIZE_STRING);
$lastname = filter_input(INPUT_POST, 'lastname', FILTER_SANITIZE_STRING);
$inviteid = filter_input(INPUT_POST, 'inviteid', FILTER_SANITIZE_STRING);
$address = filter_input(INPUT_POST, 'address', FILTER_SANITIZE_STRING);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error" style="color:red; font-size:16px;>* The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error" style="color:red; font-size:16px;>* Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error" style="color:red; font-size:16px;">* A user with this email address already exists.</p>';
$stmt->close();
}
} else {
$error_msg .= '<p class="error" style="color:red; font-size:16px;>* Database error Line 39</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error" style="color:red; font-size:16px;">* A user with this username already exists</p>';
$stmt->close();
}
} else {
$error_msg .= '<p class="error" style="color:red; font-size:16px;>* Database error line 55</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE myid = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s',$_POST['inviteid']);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 0) {
// A user with this us
$error_msg .= '<p class="error" style="color:red; font-size:16px;">* No user with this id exists</p>';
$stmt->close();
}
} else {
$error_msg .= '<p class="error" style="color:red; font-size:16px;>* Database error line 55</p>';
$stmt->close();
}
//1.86€y9.31€$Ac2w6xufmG.jI3F/5GZhDOdW1TzAPrnJ3oPF0seGHI6g03QopB4C
// TODO:
// We'll also have to account for the situation where the user doesn't have
// rights to do registration, by checking what type of user is attempting to
// perform the operation.
if (empty($error_msg)) {
// Create hashed password using the password_hash function.
// This function salts it with a random salt and can be verified with
// the password_verify function.
$passwords = password_hash($password,PASSWORD_BCRYPT);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password,firstname,lastname,phone,address,inviteid) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssssssss', $username, $email, $passwords, $firstname, $lastname, $phone, $address, $inviteid);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
}
}
/*if (login($_POST['email'],$_POST['p'], $mysqli) == true) {
// Login success
header('Location: dashboard.php');
}else{
// Login failed
//header('Location: login.php');
} */
// header('Location: dashboard.php');
//exit();
}
}
?>
process_login.php
<?php
include_once 'db_connect.php';
include_once 'functions.php';
include_once '../securimage/securimage.php';
//$securimage = new Securimage();
sec_session_start(); // Our custom secure way of starting a PHP session.
if (isset($_POST['email'], $_POST['p'])) {
$email = $_POST['email'];
$password = $_POST['p']; // The hashed password.
if (login($email, $password, $mysqli) == true) {
// Login success
// header("Location: ../protected_page.php");
header('Location: ../dashboard.php');
}else{
// Login failed
header('Location: ../login.php?error=1');
}
} else {
// The correct POST variables were not sent to this page.
header('Location: ../error.php?err=Could not process login');
exit();
}
Hi there I am trying to hash my passwords with password_hash() in PHP. This part is fine but to compare the hash is returning false no matter what. To log in I check the user account database and grab the password hash then compare it to the password typed in.Have checked all solutions here.
My code looks like this:
function login($email, $password, $mysqli) {
// Using prepared statements means that SQL injection is not possible.
if ($stmt = $mysqli->prepare("SELECT id, username, password, myid, firstname, lastname,status,ambLevel
FROM members
WHERE email = ?
LIMIT 1")) {
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_id, $username, $db_password, $myid, $fname, $lname, $status,
$ambLevel);
$stmt->fetch();
var_dump($db_password);
var_dump($password);
if ($stmt->num_rows == 1) {
// If the user exists we check if the account is locked
// from too many login attempts
if (checkbrute($user_id, $mysqli) == true) {
// Account is locked
// Send an email to user saying their account is locked
return false;
} else {
// Check if the password in the database matches
// the password the user submitted. We are using
// the password_verify function to avoid timing attacks.
if (password_verify($password,$db_password)) {
// Password is correct!
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS protection as we might print this value
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['user_id'] = $user_id;
// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/",
"",
$username);
$_SESSION['username'] = $username;
$_SESSION['firstname'] = $fname;
$_SESSION['lastname'] = $lname;
$_SESSION['myid'] = $myid;
$_SESSION['email'] = $email;
$_SESSION['status'] = $status;
$_SESSION['ambLevel'] = $ambLevel;
$_SESSION['login_string'] = hash('sha512',
$db_password . $user_browser);
// Login successful.
return true;
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
$mysqli->query("INSERT INTO login_attempts(user_id, time)
VALUES ('$user_id', '$now')");
return false;
}
}
} else {
// No user exists.
return false;
}
}
}
Please kindly help. View my full source code here.
Works as expected...
<?php
$hash=password_hash("password", PASSWORD_DEFAULT);
if (password_verify("password", $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
?>
I've had the same issue, and resolved it by setting the password column in my DB to a sufficiently long (255) VARCHAR instead of CHAR or NCHAR variable. If this doesn't help, try var_dump at all the transfer points: when first hashing, taking it from the database itself, and after submitting your query.
This question already has answers here:
Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables 11 [closed]
(2 answers)
Closed 11 months ago.
I am not sure what is wrong, everything seems to be fine.
Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables on line 88
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include_once 'db_connect.php';
include_once 'ex-config.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'])) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error">A user with this username already exists</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
$stmt->close();
}
// TODO:
// We'll also have to account for the situation where the user doesn't have
// rights to do registration, by checking what type of user is attempting to
// perform the operation.
if (empty($error_msg)) {
// Create hashed password using the password_hash function.
// This function salts it with a random salt and can be verified with
// the password_verify function.
$password = password_hash($password, PASSWORD_BCRYPT);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password) VALUES (?, ?, ?)")) {
$insert_stmt->bind_param('ssss', $username, $email, $password); // THIS IS LINE 88
// Execute the prepared query.
if (! $insert_stmt->execute()) {
// header('Location: ../error.php?err=Registration failure: INSERT');
// exit;
trigger_error("there was an error....".$mysqli->error, E_USER_WARNING);
}
}
else (header('Location: ../register_success.php'));
exit;
}
}
Source: http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
bind_param('ssss', $username, $email, $password);
^^^^ ^ ^ ^
|||| | | |
4 parameters 1 2 3 4?
4 !== 3
I guess if you remove a 's' can solve your problem:
$insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password) VALUES (?, ?, ?)")) {
$insert_stmt->bind_param('sss', $username, $email, $password); // THIS IS LINE 88
Im trying to create a register script. This is my first time trying to create a secure register page using functions in php. The issue i get is with the error "Database Error line 55 " and "Database error line 39" I followed an example from the internet but am not quite sure why im getting the errors.
Heres the code:
register.inc.php:
Register.inc.php
<?php
include_once 'db_connect.php';
include_once 'connection.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'])) {
// Sanitize and validate the data passed in
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Not a valid email
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
// Username validity and password validity have been checked client side.
// This should should be adequate as nobody gains any advantage from
// breaking these rules.
//
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing email
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
//$stmt->close();
}
// check existing username
$prep_stmt = "SELECT id FROM members WHERE username = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this username already exists
$error_msg .= '<p class="error">A user with this username already
exists</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error line 55</p>';
//$stmt->close();
}
// TODO:
// We'll also have to account for the situation where the user doesn't have
// rights to do registration, by checking what type of user is attempting to
// perform the operation.
if (empty($error_msg)) {
// Create a random salt
//$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); // Did not
work
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Create salted password
$password = hash('sha512', $password . $random_salt);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, salt)
VALUES (?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
}
}
header('Location: ./register_success.php');
}
}
Im trying to add more fields to my database registration form. I want to add "firstname" and "lastname" and have already added the columns in the database as well as the fields on the signup form. However I dont know what to change on the actual form that connects to the database (register.inc.php) Any ideas would be appreciated!
<?php
include_once 'db_connect.php';
include_once 'psl-config.php';
$error_msg = "";
if (isset($_POST['username'], $_POST['email'], $_POST['p'])) {
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$email = filter_var($email, FILTER_VALIDATE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
}
} else {
$error_msg .= '<p class="error">Database error</p>';
}
if (empty($error_msg)) {
$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
$password = hash('sha512', $password . $random_salt);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, salt) VALUES (?, ?, ?, ?)")) {
$insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
exit();
}
}
header('Location: ./register_success.php');
exit();
}
}
You'll need to:
Update your html form to add the new fields
Update your PHP code to read those values in with
$firstname = filter_input(INPUT_POST, 'firstname', FILTER_SANITIZE_STRING);
$lastname = filter_input(INPUT_POST, 'lastname', FILTER_SANITIZE_STRING);
Update the MYSQLi prepare to include the firstname and lastname (note the extra tags and ?'s)
$insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, salt, firstname, lastname) VALUES (?, ?, ?, ?, ?, ?)"))
Update the bind to add the first name and last name
$insert_stmt->bind_param('ssssss', $username, $email, $password, $random_salt, $firstname, $lastname);
I would put it into an array, so it will save me time if I needed to add more columns.
<?php
include_once 'db_connect.php';
include_once 'psl-config.php';
$error_msg = "";
$arr=['username','email','p','firstname','lastname','salt'];
$arrvalues=new Array(arr.length())
for($i=0;$i<$array.length();$i=$i+1){
if (isset($_POST[$arr[$i]]&& !empty($_POST[$arr[$i])) {
$arrvalues[$i] = filter_input(INPUT_POST,$arr[$i], FILTER_SANITIZE_STRING);
if($arr[$i]=="email"){
$arrvalues[$i]=filter_var($arrvalues[$i], FILTER_VALIDATE_EMAIL);
if (!filter_var($arrvalues[$i], FILTER_VALIDATE_EMAIL)) {
$error_msg .= '<p class="error">The email address you entered is not valid</p>';
}
}
if($arr[$i]=="password"){
if (strlen($arrvalues[$i]) != 128) {
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}
}
}
}
$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
if($stmt){
$stmt->bind_param('s', $arrvalues[1]);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
}
} else {
$error_msg .= '<p class="error">Database error</p>';
}
if (empty($error_msg)) {
$arrvalues[5] = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
$arrvalues[2] = hash('sha512', $arrvalues[2] . $arrvalues[5]);
// Insert the new user into the database
for($i=0;$i<$array.length();$i=$i+1){
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (".$arrvalues[$i].") VALUES (?)")) {
$insert_stmt->bind_param('ssss', $arrvalues[$i]);
// Execute the prepared query.
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
exit();
}
}
}
header('Location: ./register_success.php');
exit();
}