PHP with PDO and SQLS using prepared statments - php

I have recently started to learn php and currently i am working on a project in which i have to send and get information to a MSSQLS Database. I have heard PDO is the right way, so i managed to make the following code reading some tutorial:
$email = $_POST['email'];
$password = $_POST['password']; // The hashed password.
$connection = new PDO('sqlsrv:Server='. HOST .';Database=' . DATABASE, USER, PASSWORD);
$connection->query("use sub_secure_login");
$query = 'SELECT ID, username, password FROM members WHERE email = ?';
// Prepare the query
$stmt = $connection->prepare($query);
// Set the arguments array
$array = array($email);
// Execute the prepared query with the specified params
$stmt->execute($array);
$fetch = $stmt->fetch();
error_log('id: ' . $fetch['ID']);
error_log(' username: ' . $fetch['username']);
error_log(' password: ' . $fetch['password']);
SQL table name: members
with the following columns: ID - username - password
Basically, $email = $_POST['email'] is submited by a login form.
I dont know what is wrong in my code. Not sure if it is the query that is wrong, or something else. No error is shown in php_error_log and the loggs that i made are returning nothing but id, username, password.
Any help would be apreciated, and if possible, more information about using PDO, prepared statments with MSSQLS

Related

PHP PDO Service No Data

I have the below REST web service that I am using to get user information from User table:
$name = htmlentities($_GET["name"]);
$name = strtoupper($name);
$dbh = new PDO("oci:dbname= $dbhost", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $dbh->prepare("select * from Users where username =:name");
$sth->bindParam(':name', $name);
$sth->execute();
$result = array();
$result["User"] = $sth->fetchAll((PDO::FETCH_ASSOC));
print_r ($result); //returns no data
When I print out the results, no data is returned. If I hard code a username value instead of using :name, then data comes back:
$sth = $dbh->prepare("select * from Users where username ='TESTUSER'");
I am not sure what I am doing wrong with the binding of the variable that is causing the SQL to run incorrectly. I tried using bindValue and bindParam and still returns no data. I am not recieving any errors, just no data.
UPDATE: It looks like the syntax is correct. Is there anything on the Oracle side that would prevent a prepared statement from being run?
I figured out why data wasn't returning on the query. The database has the username field set as a CHAR(8) and usernames that were being passed only had 7 characters so it was failing. I need to append a blank space at the end of the string for it to match.

Password verification php form

Here I have some php code which allows me to update User information in my students table.
I am trying to figure out how am I able to check if the password for the user that is currently logged in matches the password stored in the database before allowing information can be updated.
As the others say, your script has bunch of holes.
I assume you are developing for local area only.
if you host it at this stage, surely you will get security problems.
Alright, back to your question.
There are several ways to validate user before commit update.
For example:
Put sql condition when updating the change
if(isset($_POST['Update'])){
$UpdateFName = $_POST['FirstName'];
$UpdateLName = $_POST['LastName'];
$UpdateEmail = $_POST['Email'];
$UpdateFPassword = $_POST['Password'];
$SQL = $conn->query("UPDATE students
SET FName='{$UpdateFName}',LName='{$UpdateLName}',Email='{$UpdateEmail}',Password='{$UpdateFPassword}'
WHERE UserID = $User and Password = '$_SESSION["PW"]' ");
header('Location:updateinfo.php');
}
if you use this method, if the current password is different with password that stored in db, those edit sql won't run, since where condition is invalid
validate the user first.
if(isset($_POST['Update'])){
$UpdateFName = $_POST['FirstName'];
$UpdateLName = $_POST['LastName'];
$UpdateEmail = $_POST['Email'];
$UpdateFPassword = $_POST['Password'];
$sqlValidate = $conn->query("SELECT * FROM students WHERE UserID ='$User' and Password='$_SESSION["PW"]' ");
$getUser = $sqlValidate -> fetch_array(MYSQLI_BOTH);
if($getUser['UserID'] != ''){
$SQL = $conn->query("UPDATE students SET FName='{$UpdateFName}', LName='{$UpdateLName}', Email='{$UpdateEmail}', Password ='{$UpdateFPassword}' WHERE UserID = $User ");
}// end if
header('Location:updateinfo.php');
}
you can read http://php.net/manual/en/function.crypt.php for password encryption.
your form basically has no validations. Also, there are opportunities for SQL injections.
validate your email field before posting it. try:
if(!filter_var($email_variable,FILTER_VALIDATE_EMAIL){
//throw some kind of exceptions or kill the process
}
I also advise that you use PDO as it supports the use of prepared statements. There is an amazing function there can bindParam() which binds your parameters.
TRy:
$DBH = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$STH = $DBH->prepare("SELECT * FROM student_table WHERE studentID= :id");
$id = 1; // here you should keep it as variable and pass it to param
$STH->bindParam(':id', $id, PDO::PARAM_STR);
$STH->execute();
$STH->setFetchMode(PDO::FETCH_ASSOC);
Also, do not post raw passwords directly to your database. Either use the inbuilt php hashing algorithm or use some kind of encryption function to secure them.

Query was empty with MySQL select Query

So I'm new to php and mysql and over the past few days have created a log in system using php and mysql. I am trying to make a function where a user can change their password with the following query:
$query2 = mysql_query("SELECT password FROM adminusr WHERE id =$idToChange");
$result = mysql_query($query2) or die($idToChange.mysql_error());
With SELECT statements you only select rows. To change them you need UPDATE. Consider using PDO because mysql_* functions are deprecated. Also try to hash your passwords and don't store them in plain text.
You need something like this:
$query2 = mysql_query("UPDATE adminusr SET password = '$new_password' WHERE id = '$idToChange'");
Using PDO
//Make the connection using PDO
try {
$conn = new PDO("mysql:host=$hostname;dbname=mysql", $username, $password);
echo "PDO connection object created";
}
catch(PDOException $e) {
echo $e->getMessage();
}
//Make your query
$sql = 'UPDATE adminusr SET password = :new_password WHERE id = :id';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':new_password'=>$new_password, ':id'=>$idToChange));
EDIT answering to comment
Then you need to have also username and password fields at your form. So, you need four fields: username, oldPassword, newPassword, confirmNewPassword. Before the update statement you need to select the user having credentials username, oldPassword. If you find only one then you have to check if newPassword and confirmNewPassword match. If match then proceed to update. Otherwise print some error message.

What is the proper way to escape a $_SESSION username for use in a mysql query?

I am using the stored $_SESSION username:
$usernameunesc = htmlentities($_SESSION['username'], ENT_QUOTES, 'UTF-8');
and escaping the variable as follows:
$username = mysqli_real_escape_string($link, $usernameunesc);
and then using it to perform the following query:
$query = mysqli_query($link, "SELECT id FROM users WHERE username = '".$username."'");
The last query returns an output of
1111
If I remove $username from the query and change it to 'demo' (which is what the username actually is) the query returns an id of 12 successfully, but using the $username variable does not work. Am I not properly escaping the string? Is there a better way to do this? By the way, I can also perform the query in the SQL command line and it works fine, so I know the query isn't the problem.
As you are using mysqli, I suggest you use a prepared statement - it will automatically escape the variable.
if ($stmt = $mysqli->prepare("SELECT id FROM users WHERE username =?")) {
/* bind parameters for markers */
$stmt->bind_param("s", $usernameunesc);
/* execute query */
$stmt->execute();
}
Full example right here http://php.net/manual/en/mysqli.prepare.php

Is mysql_real_escape_string() unsafe against hexadecimal encoded data?

We know that all user input must be escape by mysql_real_escape_string() function before executing on mysql in php script. And know that this function insert a \ before any ' or " character in user input. suppose following code:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='".mysql_real_escape_string($_POST['username']."' AND password='".mysql_real_escape_string($_POST['password']."'";
mysql_query($query);
// This means the query sent to MySQL would be:
echo $query;
this code is safe.
But I find out if user enters her inputs with hexadecimal format then mysql_real_escape_string() can not do any thing and user can execute her sql injection easily. in bellow 27204f522027273d27 is same ' OR ''=' but in hex formated and sql execute without problem :
$_POST['username'] = 'aidan';
$_POST['password'] = "27204f522027273d27";
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='".mysql_real_escape_string($_POST['username']."' AND password='".mysql_real_escape_string($_POST['password']."'";
mysql_query($query);
// This means the query sent to MySQL would be:
echo $query;
But whether this is true and if answer is yes how we can prevent sql injection in this way?
If you are using mysql_real_escape_string(), odds are you would be better served using a prepared statement.
For your specific case, try this code:
/*
Somewhere earlier in your application, you will have to set $dbh
by connecting to your database using code like:
$dbh = new PDO('mysql:host=localhost;dbname=test', $DBuser, $DBpass);
*/
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
$user = $_POST['username'];
$password = $_POST['password'];
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user=? AND password=?";
$stmt = $dbh->prepare($query);
$stmt->bindParam(1, $user);
$stmt->bindParam(2, $password);
$stmt->execute();
This does require you to use PDO for your database interaction, but that's a good thing overall. Here's a question discussing the differences between PDO and mysqli statements.
Also see this StackOverflow question which is remarkably similar to yours and the accepted answer, from which I poached some of this answer.

Categories