Converting different code from MySQL to MySQLi - php

I'mm currently going through the process of changing my code and have hit a bit of a wall so thought id ask and see if anyone can help me with the new code...
firstly i have quite a few mysql_result() dotted around my code and would like to know how to write the code for the new process.. here is an example of one of my functions that has code that needs changing, I've done some its the mysql_result() part that I need to know how to rewrite..
function user_exists($db,$username) {
$username = sanitize($db,$username);
$sql = $db->query("SELECT COUNT(`user_id`) FROM `users` WHERE `username` = '$username'");
return(mysql_result($sql, 0) == 1) ? true : false;
}
Also while I'm here I may as well ask.. I also have this function to, well sanitize code but i keep reading that mysql_real_escape_string is not so safe. I've read that i should be using prepared statements, I'm just not to sure how to implement it into my code..here is the sanitize function that is basically just mysql_real_escape_string()..
function sanitize($db, $data) {
return mysqli_real_escape_string($db, $data);
}
so how would i make this correct? cause from what im reading its just putting prepare before a query like..
$sql = $db->prepare("SELECT COUNT(`user_id`) FROM `users` WHERE `username` = '$username'");
so my question is, can anyone help me change these codes to correct up-to date versions?

What you want to use is the PDO Class and bind values (http://www.php.net/manual/en/class.pdo.php).
So something like the following should work:
$stmt = $db->prepare("SELECT 1 FROM users WHERE username = ?");
$stmt->execute([$username]);
return $stmt->fetchColumn();

Related

How to escape during PDO query statement in php? [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 7 years ago.
(Edit:Guys, Before jumping to any conclusions, I'm asking how do you escape a query variable from the Example#2 from php.net website. I tried lot of ways but they all gave me errors. If you can please read that Example and post your version of that exact Example#2. Also please read about why they have that example there.)
I was searching for a reliable 'row:count' method to use with PHP PDO across multiple database types, and came across below code from php.net
http://php.net/manual/en/pdostatement.rowcount.php (See Example:#2)
It says to do a row count to see if an entry exists in a database using a SELECT statement, the error proof method is to use PDO::query() instead of PDOStatement::fetchColumn().
My question is I know how to bind and execute with PDO, but I don't know how to assign a user submitted variable($username) to this $sql statement and escape it successfully?
Is it possible to bind parameters to this $sql mehod using PDO?
try{
$conn = new PDO($dsn, $db_username, $db_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->db = $conn;
} catch(PDOException $e){
echo 'Error:'.$e;
}
public function usernameExists($username){
//Check db for a match.
$sql = "SELECT * FROM users WHERE username = '".$username."'";
$results = $this->db->query($sql);
if($results->fetchColumn() > 0){
//Matching username found in the db
return true;
}else{
//No matching username in db
return false;
}
}
You're looking for bindValue. With it, you can use a placeholder when writing your query, then pass the user's input afterward.
For example:
public function usernameExists($username){
//$result = $this->db->query('SELECT * FROM users WHERE username = ');
//Check db for a match.
$sql = "SELECT * FROM users WHERE username = :username";
$s = $conn->prepare($sql);
$s->bindValue(':username',$username);
$s->execute();
$results = $s->fetchAll();
if(count($results) > 0){
//Matching username found in the db
return true;
}else{
//No matching username in db
return false;
}
For more info, see the PHP manual.
You're going to want to use a parameterized query like this:
<?php
$value = "whatever";
$stmt = $dbh->prepare("SELECT * FROM TABLE_NAME where column_name = ?");
if ($stmt->execute(array($value))) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
?>
If you really wanted to quote+escape the string, then that's possible too. It even looks somewhat more legible with complex variable interpolation than your original string patching:
$sql = "SELECT * FROM users WHERE username = {$this->db->quote($username)}";
// ->quote itself adds ↑ 'quotes' around
Now of course: don't do that. Use a placeholder, and pass it per ->execute([$var]); instead. Strive for consistency.

Writing a Select Where statement in PHP and MySQL

Would someone please me with the code below, I am inexperienced in this area and my class in SQL was "A long time ago in a galaxy far, far away..." I know the connection string works because I have used it in other functions with this app. I have even used the code below for retrieving *rows from another table in another function, for the most part, except that I didn't use the WHERE clause.
First, I am able to store IP addresses in the table using a function and it is working well. Now I want to check to see if a given one exist in this table. Partial code is given below.
What seems to always return is 0 rows. I have put in test data into the table and hard-coded the $ipA, but I still get 0 rows return. Please help if possible and thanks for the effort spent.
function checkDB($ipA) {
require_once('connection.inc.php');
$resultAns = "";
//create db connection
$conn = dbConnect();
//init prepared stmt
$stmt = $conn->stmt_init();
//Set sql query for ipAddress search
//prepare the SQL query
$sql = 'SELECT * FROM ipAddress WHERE ipA = ?';
//submit the query and capture the result
if ($stmt->prepare($sql)) {
$stmt->bind_param('s', $ipA);
$stmt = $stmt->execute();
//if qry triggers error affeted_rows value becomes -1 &
//php treats -1 as true; so test for greater than 0
$numRows = $stmt->num_rows; //not to sure about the syntax here
}
// I want to know if the query brought back something or not, I don't what
// to know exactly what, only that it found a match or did not find a match.
// echos are for testing purposes to show me where I am landing.
if ($numRows == 0) {
echo '<script type="text/javascript">window.alert("numRows = 0")</script>';
$resultAns = 0;
} elseif ($numRows == 1) {
echo '<script type="text/javascript">window.alert("numRows = 1")</script>';
$resultAns = 1;
}
return $resultAns;
}
Try storing the result after you execute
$stmt->store_result();
Use $stmt->store_result(); before you call num_rows.
While the others caught one reason that $numRows would never receive a value other than 0, the other piece of code that was flawed and caused problems was...
$stmt = $stmt->execute(); which should have been just $stmt->execute();
I must have mixed it up with other code I wrote from somewhere else.
Thanks for the answers, they did help.

mysqli database functions set up

I've been trying to write a function to draw a usernames name from the database fetch he result then return it back to the parent page but nothing I have tried works and I don't even know where to go from here. my old code that I used mysql on works perfect and was easy to put together but this mysqli and all its double parameters and stuff I cant figure it out. so basically I am asking for anyone who knows how to set one of these up.
(SELECT name FROM users WHERE username = '" .$_SESSION['username']. "')
I want to mysqli_real_escape the value if possible so if anyone knows how to set up a function to return a value back to its parent page I would much appreciate it.
It's very similar to using mysql_* functions:
function get_user_name()
{
global $conn;
$sql = "SELECT name FROM users WHERE username = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("s", $_SESSION['username']);
$stmt->execute();
$result = $stmt->get_result();
$data = mysqli_fetch_assoc($result);
return $data['name'];
}
}

Code for Updating MySQLI PHP

A few keep telling me that my code for updating data in my mysqli query is extremely insecure. Actually, several people on this site. So I would like to know what they say would secure my code below so it is secure when updating my database. I would like to know how the would secure my mysqli query.
Okay, in my code for my database entries, this is what I do. Let me start by saying that I always send via POST method to avoid browser url complications.
When I get the POST data, this is my code.
$ID = 1;
$DATA = htmlentities(addslashes($_POST['data']));
$FIELD = "lifename";
$DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
$DBRESULT = $MYSQLI->query($DBQUERY);
I am currently using this on my local site.
How is this unsafe if I have escaped all quotes, all slashes, all ampersands (from javascript through ajax) and all semi colons? How is this vunerable?
So can you tell me what I should change when adding information to my database.
Thanks
PS ... I am using mysqli and will continue to use it. Thanks
A few suggested that I change from mysqli to pdo, but I am not willing to completely 100% change how I access data from my databases. Someone posted another link before about prepare and bind_param and this is what I am going to use. So thank you.
This is now my code, and binding params is supposed to make it so that each param is only for the one part of my query and can not be for anything else, nothing else at all.
$DBQUERY = "UPDATE `lifetable` SET `lifename` = ? WHERE `id` = ?"; // EACH ? IS A PART OF bind_param BELOW IN ORDER AFTER TYPE.
$STMT = $MYSQLI->prepare($DBQUERY);
$STMT->bind_param('si', $DATA, $ID); // THIS MAKES SURE THAT THE VARIABLES ARE ONLY USED FOR THERE PLACE HERE AND NOTHING ELSE. ? in order.
$DATA = htmlentities($_POST['data']); // I STILL USE MY CODE HERE TO REMOVED ANY OTEHR CHARACTERS, JUST INCASE. AND BEFORE IT GETS HERE, IT USES encodeURIComponent TO OUTPUT FROM AJAX.
$ID = $COLUMN[1];
$STMT->execute();
$STMT->close();
My code worked before and it works now, just more secure, or so I am told.
Use PDO Class like:
$db = new PDO('mysql:host=localhost;dbname=<SOMEDB>', '<USERNAME>', 'PASSWORD');
$query = $db->prepare('UPDATE `lifetable` SET :FIELD = :DATA WHERE `id` = :ID');
$query->execute(array(
':FIELD' => $field,
':DATA' => $data,
':ID' => $id
));
$query->commit();
For more info Are there good tutorials on how to use PDO?
i think your security lies in the SQL injection, and the best way i know to make the query secure is using mysql_real_escape_string on the var. Here an example taken from php.net
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$city = $mysqli->real_escape_string($city);
$mysqli->query("INSERT into myCity (Name) VALUES ('$city')")
you can apply the same procedure to your query
$ID = 1;
$DATA = $MYSQLI->real_escape_string($_POST['data']));
$FIELD = "lifename";
$DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
$DBRESULT = $MYSQLI->query($DBQUERY);
I edited the above because I forgot the quotes for lifename in my question. They should be there as they are in my original code.
now tour query should be secure :D
here the reference to php.net documentation :
http://cn2.php.net/manual/en/mysqli.real-escape-string.php

Is this vulnerable to SQL injection

I realize there are a lot of questions already about this. But my method isn't the same as theirs, so I wanted to know. I think I understand SQL, but I don't want to risk making a mistake in the future, so thanks for any help. (This is just a project I'm doing, not homework or anything important).
function checkLogin($username, $password) {
$username = strtolower($username);
connectToDatabase();
$result = mysql_query("SELECT * FROM `users` WHERE username='$username'");
$dbpassword = "";
while($row = mysql_fetch_array($result))
{
$rowuser = $row['username'];
if($username != $row['username']) continue;
$dbpassword = $row['password'];
}
if($dbpassword == "") {
return false;
}
$genpass = generatePassword($password);
return $genpass == $dbpassword;
}
So hit me with your best shot :)
And I don't think my method is as efficient as it could be. I don't understand php enough to understand what $row = mysql_fetch_array($result) is doing unfortunately.
Because you are taking an arbitrary string and placing it directly into an SQL statement, you are vulnerable to SQL injection.
( EDITED based on a comment below. )
The classic example of SQL injection is making a username such as the following:
Robert'); DROP TABLE users;--
Obligatory XKCD link
Explanation:
Given the "username" above, interpolation into your string results in:
SELECT * FROM `users` WHERE username='Robert'); DROP TABLE users;--'
The comment symbol -- at the end is required to "get rid" of your closing quote, because I just substituted one of mine to end your select statement so that I could inject a DROP TABLE statement.
As #sarnold pointed out, PHP's mysql_query only executes a the first query in the string, so the above example (known as query stacking) does not apply. The function is explained here: http://php.net/manual/en/function.mysql-query.php.
A better example can be found here. Here they use a username of
' OR 1 OR username = '
which interpolated becomes
SELECT * FROM `users` WHERE username='' OR 1 OR username = ''
and which would cause your application to retrieve all users.
The short answer is yes.
A perhaps more helpful answer is that you should never trust user input; prepared statements are the easiest way to protect against this, if you have PDO available. See PDO Prepared Statements
<?php
$stmt = $dbh->prepare("SELECT * FROM `users` WHERE username=?");
if ($stmt->execute($username)) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
?>
The other answers are an excellent description of your problem, however, I think they both overlook the best solution: use PHP's PDO Prepared Statements for your queries.
$stmt = $dbh->prepare("SELECT * FROM users where username = ?");
if ($stmt->execute(array($username))) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
This is a small, simple example. There are more sophisticated ways of using PDO that might fit your application better.
When you use PDO prepared statements you never need to manually escape anything and so long as you use this slightly different style, you will never write an SQL injection vulnerability and you don't have to maintain two variables per underlying "data" -- one sanitized, one as the user supplied it -- because only one is ever required.
I would say yes it is open to SQL injection.
This is because you are taking user input in the form of $username and putting it into your SQL statement without making sure it is clean.
This is a function that I like to use in my applications for the purpose of cleaning strings:
function escape($data) {
$magicQuotes = get_magic_quotes_gpc();
if(function_exists('mysql_real_escape_string')) {
if($magicQuotes) {
$data = stripslashes($data);
}
$data = mysql_real_escape_string($data);
}
else {
if(!$magicQuotes) {
$data = addslashes($data);
}
}
return $data;
}
Then you can use it like this:
$username = escape(strtolower($username));
connectToDatabase();
$result = mysql_query("SELECT * FROM `users` WHERE username='$username'");

Categories