PHP Protect query from mysql Injection. - php

How can I add mysql_real_escape_string() to this:::
$result = mysql_send("INSERT customers SET user='$username', pword='$pass1',
firstname='$firstname', lastname='$lastname', email='$email',
active='No', activecode='$activecode', dateofbirth='$dateofbirth',
gender='$gender', title='$title', occupation='$occupation',
address='$address', city='$city', country='$country', zip='$zip',
mobile='$mobile', telephone='$telephone', fax='$fax',
website='$website'
");

$result = mysql_send(" INSERT customers
SET user='".mysql_real_escape_string($username)."',
pword='".mysql_real_escape_string($pass1)."',
firstname='".mysql_real_escape_string($firstname)."',
lastname='".mysql_real_escape_string($lastname)."',
email='".mysql_real_escape_string($email)."',
active='No',
activecode='".mysql_real_escape_string($activecode)."',
dateofbirth='".mysql_real_escape_string($dateofbirth)."',
gender='".mysql_real_escape_string($gender)."',
title='".mysql_real_escape_string($title)."',
occupation='".mysql_real_escape_string($occupation)."',
address='".mysql_real_escape_string($address)."',
city='".mysql_real_escape_string($city)."',
country='".mysql_real_escape_string($country)."',
zip='".mysql_real_escape_string($zip)."',
mobile='".mysql_real_escape_string($mobile)."',
telephone='".mysql_real_escape_string($telephone)."',
fax='".mysql_real_escape_string($fax)."',
website='".mysql_real_escape_string($website)."'
");

I make it this way (assuming HTML form's field names exactly match a database field name):
$fields = explode(" ","user pword firstname lastname email ative activecode dateofbirth gender title occupation address city country zip mobile telephone fax website");
$_POST['active'] = "Mo"; // I know it's kinda dirty but it works.
$sql = "INSERT INTO customers SET ".makeDdbSet($fields);
function makeDdbSet($fields) {
$q='';
foreach ($fields as $v) $q.="`$v` = '".mysql_real_escape_string($_POST[$v])."', ";
return trim($q,", ");
}
looks neat to me.

Maybe you can take some time and check out Doctrine ORM.
Saving to database would then look like:
$customer = new Customer();
$customer->fromArray($data); // $data = array("firstname"=>"John", ...)
$customer->save();
Everything will be escaped, your program will also be more readable ...

Escaping is quite old-school. Instead, use prepared statements to separate queries and data.
This saves you lots of headaches.
$sql = "INSERT customers SET user=:user, pword = :pword .....";
$sth = $dbh->prepare($sql);
$sth->execute(array('user => $username, 'pword' => $password));
Depending on where you get the data from, you might also directly have it in an array.
For example, in case you get a lot of data from a form, with the variable names pword, user and so on you can directly use that array
$sth->execute($_POST);

$result = mysql_send("INSERT customers SET user='$username', pword='$pass1', firstname='".mysql_real_escape_string($firstname)."', lastname='".mysql_real_escape_string($lastname)."', email='".mysql_real_escape_string($email)."', active='No', activecode='".mysql_real_escape_string($activecode)."', dateofbirth='".mysql_real_escape_string($dateofbirth)."', gender='".mysql_real_escape_string($gender)."', title='".mysql_real_escape_string($title)."', occupation='".mysql_real_escape_string($occupation)."', address='".mysql_real_escape_string($address)."', city='".mysql_real_escape_string($city)."', country='".mysql_real_escape_string($country)."', zip='".mysql_real_escape_string($zip)."', mobile='".mysql_real_escape_string($mobile)."', telephone='".mysql_real_escape_string($telephone)."', fax='".mysql_real_escape_string($fax)."', website='".mysql_real_escape_string($website)."'");

Related

I am trying update multiple rows using values is this correct?

$query = "UPDATE INTO Sanctions SET (idNumber, lastName,firstName, section,sanction,expireDate) VALUES('$idNumber','$lastName', '$firstName','$section','$sanction', '$dueDate') WHERE id= '$id'";
Wrong
$query = "UPDATE INTO Sanctions
SET (idNumber, lastName,firstName, section,sanction,expireDate)
VALUES('$idNumber','$lastName', '$firstName','$section','$sanction', '$dueDate')
WHERE id= '$id'";
Correct way:
$query = "UPDATE Sanctions
SET idNumber = '{$idNumber}',
lastName = '{$lastName}', ....
WHERE id = '{$id}'";
The INTO command is not valid for UPDATE query. You need to assign the table equals to (=) values for every column you want to edit.
Notes:
These query are not well secured, please use prepared statement insted. :)

Conditional PDO Delete statement probably not working

The portion that is trying to delete duplicate entries in the database seems incorrect. So I suppose I am asking what would be the correct way to do that in this example. I am not totally new to PHP , but this is beyond me. If you could please tell me what is wrong and how to fix that would be greatly appreciated.
Now on to what I am trying to accomplish. I have a multidimensional array filled with values that is generated by a function. What I am trying to do is if there is a value in the array that already exists in the database delete it. Code:
enter code here
if(is_array($items)){
$values = array();
foreach($items as $row => $value){
$rsn = mysqli_real_escape_string($connect, $value[0]);
$rank = mysqli_real_escape_string($connect, $value[1]);
$values[] = "('', '$rsn', '$rank', '')";
$sql = "SELECT id FROM users WHERE rsn = :rsn";
$query = $conn->prepare($sql);
$query->execute(array(":rsn" => $value[0]));
$results = $query->rowCount();
while($deleted = $query->fetch(PDO::FETCH_ASSOC)){
$sql = "DELETE FROM users WHERE id = :id";
$query = $conn->prepare($sql);
foreach($deleted as $delete){
$query->execute(array(':id' => $delete));
}
}
}
//user_exists_delete($conn, $rsn);
$sql = "INSERT INTO users(id, rsn, rank, points) VALUES ";
$sql .= implode(', ', $values);
if(!empty($rank)&& !empty($rsn)){
if(mysqli_query($connect, $sql)){
echo "success";
}else{
die(mysqli_error($connect));
}
}
}
EDIT: I have got it partially working now, just need it to delete all dupes instead of only one. I edited code to reflect changes.
There are a couple problems, if you didn't strip much of your original code and if you don't need to do more than just what you shown why not just send a delete instruction to your database instead of checking validity first?
You have
//Retrieve ID according to rsn.
$sql = "SELECT id FROM users WHERE rsn = :rsn ";
//Then retrieve rsn using rsn??? Useless
$sql = "SELECT rsn FROM users WHERE rsn = :rsn ";
//Then delete using ID, retrieved by rsn.
$sql = "DELETE FROM users WHERE id = :id";
All those could simply be done with a delete using rsn...
$sql = "DELETE FROM users WHERE rsn = :rsn";
The row won't be deleted if there are no rows to delete, you don't need to check in advance. If you need to do stuff after, then you might need to fetch information before, but if not, you can use that while still checking the affected rows to see if something got deleted.
Now, we could even simplify the script by using only one query instead of one per user... We could get all rsn in an array and then pass it to the DELETE.
$sql = "DELETE FROM users WHERE rsn in :rsn";
//Sorry not exactly sure how to do that in PDO, been a while.
I fixed it I just omitted the WHERE clause in the delete statement so all records are being deleted before that insert gets ran again.

Insert into MYSQL Database WHERE username = :username

So, im struggling with this for 2 days, i havent seen any example on google about that it works, so i guess it doesnt work like this:
$steamusername = "xx";
$uname = $_SESSION['username'];
$sql1 = "INSERT INTO users (steamusername) VALUES ( :steamusername) WHERE :username = username";
$query = $conn->prepare( $sql1 );
$result = $query->execute( array( ':steamusername'=>$steamusername, ':username'=>$uname));
It does not give any errors, but it also does not put it into the database.
I really have no idea how i can make it it goes into the user table, i also tried to update the field:
$sql1 = "UPDATE users SET steamusername = :steamusername WHERE username = :username";
$stmt1 = $conn->prepare($sql1);
$stmt1->bindParam(':username', $uname);
$stmt1->bindValue(':steamusername', $steamusername);
$stmt1->execute();
Does anyone know the solution? Thanks in advance!
INSERT is used to create a new record, what you're looking to do is update a current record. You need to use an UPDATE query, as follows:
$query = $conn->prepare( "UPDATE users SET steamusername = :steamusername WHERE username = :username" );
$query->execute(array( ':steamusername' => $steamusername, ':username' => $uname));
Notice that we pass the parameters to the execute() function as an array.

INSERTING values from one table into another table

I have this code to select all the fields from the 'jobseeker' table and with it it's supposed to update the 'user' table by setting the userType to 'admin' where the userID = $userID (this userID is of a user in my database). The statement is then supposed to INSERT these values form the 'jobseeker' table into the 'admin' table and then delete that user from the 'jobseeker table. The sql tables are fine and my statements are changing the userType to admin and taking the user from the 'jobseeker' table...however, when I go into the database (via phpmyadmin) the admin has been added by none of the details have. Please can anyone shed any light onto this to why the $userData is not passing the user's details from 'jobseeker' table and inserting them into 'admin' table?
Here is the code:
<?php
include ('../database_conn.php');
$userID = $_GET['userID'];
$query = "SELECT * FROM jobseeker WHERE userID = '$userID'";
$result = mysql_query($query);
$userData = mysql_fetch_array ($result, MYSQL_ASSOC);
$forename = $userData ['forename'];
$surname = $userData ['surname'];
$salt = $userData ['salt'];
$password = $userData ['password'];
$profilePicture = $userData ['profilePicture'];
$sQuery = "UPDATE user SET userType = 'admin' WHERE userID = '$userID'";
$rQuery = "INSERT INTO admin (userID, forename, surname, salt, password, profilePicture) VALUES ('$userID', '$forename', '$surname', '$salt', '$password', '$profilePicture')";
$pQuery = "DELETE FROM jobseeker WHERE userID = '$userID'";
mysql_query($sQuery) or die (mysql_error());
$queryresult = mysql_query($sQuery) or die(mysql_error());
mysql_query($rQuery) or die (mysql_error());
$queryresult = mysql_query($rQuery) or die(mysql_error());
mysql_query($pQuery) or die (mysql_error());
$queryresult = mysql_query($pQuery) or die(mysql_error());
mysql_close($conn);
header ('location: http://www.numyspace.co.uk/~unn_v002018/webCaseProject/index.php');
?>
Firstly, never use SELECT * in some code: it will bite you (or whoever has to maintain this application) if the table structure changes (never say never).
You could consider using an INSERT that takes its values from a SELECT directly:
"INSERT INTO admin(userID, forename, ..., `password`, ...)
SELECT userID, forename, ..., `password`, ...
FROM jobseeker WHERE userID = ..."
You don't have to go via PHP to do this.
(Apologies for using an example above that relied on mysql_real_escape_string in an earlier version of this answer. Using mysql_real_escape_string is not a good idea, although it's probably marginally better than putting the parameter directly into the query string.)
I'm not sure which MySQL engine you're using, but your should consider doing those statements within a single transaction too (you would need InnoDB instead of MyISAM).
In addition, I would suggest using mysqli and prepared statements to be able to bind parameters: this is a much cleaner way not to have to escape the input values (so as to avoid SQL injection attacks).
EDIT 2:
(You might want to turn off the magic quotes if they're on.)
$userID = $_GET['userID'];
// Put the right connection parameters
$mysqli = new mysqli("localhost", "user", "password", "db");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
// Use InnoDB for your MySQL DB for this, not MyISAM.
$mysqli->autocommit(FALSE);
$query = "INSERT INTO admin(`userID`, `forename`, `surname`, `salt`, `password`, `profilePicture`)"
." SELECT `userID`, `forename`, `surname`, `salt`, `password`, `profilePicture` "
." FROM jobseeker WHERE userID=?";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param('i', (int) $userID);
$stmt->execute();
$stmt->close();
} else {
die($mysqli->error);
}
$query = "UPDATE user SET userType = 'admin' WHERE userID=?";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param('i', (int) $userID);
$stmt->execute();
$stmt->close();
} else {
die($mysqli->error);
}
$query = "DELETE FROM jobseeker WHERE userID=?";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param('i', (int) $userID);
$stmt->execute();
$stmt->close();
} else {
die($mysqli->error);
}
$mysqli->commit();
$mysqli->close();
EDIT 3: I hadn't realised your userID was an int (but that's probably what it is since you've said it's auto-incremented in a comment): cast it to an int and/or don't use it as a string (i.e. with quotes) in WHERE userID = '$userID' (but again, don't ever insert your variable directly in a query, whether read from the DB or a request parameter).
There's nothing obviously wrong with your code (apart from it being insecure with using non-escaped values directly from $_GET).
I'd suggest you try the following in order to debug:
var_dump $userData to check that the values are as you expect
var_dump $rQuery and copy and paste it into phpMyAdmin to see if your query is not as you expect
If you don't find your problem then please post back your findings along with the structure of the tables you're dealing with

PHP json_encode losing my UTF-8 escapes?

I have an array with strings with international characters.
When I save this in the database I loose the backslashes? Why?
$descr_arr = array("héééllo","world");
$js_encoded = json_encode($descr_arr);
print $js_encoded; // "[\"h\u00e9\u00e9\u00e9llo\",\"world\"]"
$sql_query = "UPDATE test_table SET description = '$js_encoded' WHERE id = 0";
$sql_res = mysql_query($sql_query);
// in the description field in the database I find:
// ["hu00e9u00e9u00e9llo","world"]
You didn't escape your database inputs. Always escape!
Here's one way
$sql_query = "UPDATE test_table SET description = '".
mysql_real_escape_string($js_encoded).
"' WHERE id = 0";
Better yet, use a database wrapper like PDO or ADODb, which would take care of the escaping for you. It would look something like this:
$db->Execute("UPDATE test_table SET description =? where id=?",
array($js_encoded, $id));

Categories