another day another question...
I need to write PHP script to update mySQL database.
For example: updating profile page when user want to change their first name, last name or etc.
Here is my php script so far, it doesn't work. Please help!
<?php
# $db = new MySQLi('localhost','root','','myDB');
if(mysqli_connect_errno()) {
echo 'Connection to database failed:'.mysqli_connect_error();
exit();
}
if (isset($_GET['id'])) {
$id = $db->real_escape_string($_GET['id']);
$First_Name2 = $_POST['First_Name2'];
$query = "UPDATE people SET $First_Name2 = First_Name WHERE `Id` = '$id'";
$result = $db->query($query);
if(! $result)
{
die('Could not update data: ' . mysql_error());
}
echo "Updated data successfully\n";
$db->close();
}
?>
THank you.
Your sql is wrong. Apart from the gaping wide open SQL injection attack vulnerability, you're generating bad sql.
e.g. consider submitting "Fred" as the first name:
$First_Name2 = "Fred";
$query = "UPDATE people SET Fred = First_name WHERE ....";
now you're telling the db to update a field name "Fred" to the value in the "First_Name" field. Your values must be quoted, and reversed:
$query = "UPDATE people SET First_name = '$First_Name2' ...";
You are also mixing the mysqli and mysql DB libraries like a drunk staggering down the street. PHP's db libraries and function/method calls are NOT interchangeable like that.
In short, this code is pure cargo-cult programming.
Related
I have created a webpage that gets the user to login, if they havent got an account then they can register and is creates a new user for them.
This is the table users in the database (user_registration)
user_id username password email wage
1 johnsmith jsmith99 jsmith#gmail.com 0
2 davidscott dscott95 davidscott#gmail.com 0
When a new user registered, the default value for the wage is 0. I want them to be able to edit this through the use of a form - this is the HTML code for the form:-
<form method="post" action="<?php $_PHP_SELF ?>">
<input name="new-wage" type="text" id="new-wage" class="textbox" placeholder="New Wage">
<input name="update" type="submit" id="update" value="Update" class="btn">
</form>
PHP Code: (note- the php and the html form are all in the same file(index.php) )
<?php
if(isset($_POST['update']))
{
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = '';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
$user_id = $_SESSION['MM_Username'];;
$wage = $_POST['new-wage'];
$query = "UPDATE users ".
"SET wage = '$wage' ".
"WHERE user_id = '$user_id'" ;
mysql_select_db('user_registration');
$retval = mysql_query( $query, $conn );
if(! $retval )
{
die('Could not update data: ' . mysql_error());
}
echo "Updated data successfully\n";
mysql_close($conn);
}
else
{
?>
When i fill in this form and hit the update button, it reloads the webpage and displays Updated data successfully which is exactly what should happen. BUT - when I refresh the table in PHP My Admin, it keeps the wage as 0, and not what i entered in the form.
Has anyone got any ideas what might be wrong with my code?
Thanks in advance for any answers.
PS.- I know that I have used the functions mysql_* and not mysqli_, simply because i dont know how to convert it, can you also help me with this??
You are vulnerable to sql injection attacks.
Plus, you don't seem to call session_start() so $_SESSION is probably empty, leading to $user_id being empty, and your query not matching anything. A simple var_dump($query) will show you what's actually going on there.
You need to check mysql_affected_rows() as well, to see if anything actually got updated.
Based on what you said in the comments:
This:
$user_id = $_SESSION['MM_Username'];
$wage = $_POST['new-wage'];
$query = "UPDATE users ".
"SET wage = '$wage' ".
"WHERE user_id = '$user_id'" ;
Should be this:
$user = $_SESSION['MM_Username'];
$wage = $_POST['new-wage'];
$query = "UPDATE users ".
"SET wage = '$wage' ".
"WHERE username = '$user'";
As you wanted to update the records based on the user id but you passed in the username as the parameter!
However, I'm assuming you want to update by the user_id, as that is unique for each user, and thus a more robust design.
To do that you'd have to add another $_SESSION variable that stores the user id when they log in. Call it $_SESSION['MM_Id'] or whatever. The name is arbitrary.
You also have an unclosed else statement at the end of your code:
else
{
?>
Either close it or remove it.
As Mark said, your code is susceptible to SQL injection attacks, a commonly abused mistake. I'd recommend looking at PDO (my personal favorite). If you're new to object-oriented programming, it may be difficult, but it offers more power, flexibility, and security. Plus, object-oriented programming is an important concept anyway.
To protect your current code from injection, use mysql_real_escape_string()...
$user = mysql_real_escape_string($_SESSION['MM_Username']);
$wage = mysql_real_escape_string($_POST['new-wage']);
$query = "UPDATE users ".
"SET wage = '$wage' ".
"WHERE username = '$user'";
This prevents people form putting in special characters (such as quotes) to attack your queries. I gotta run, but if you read up on SQL injection, you'll understand!
My update form script works only, if I use numbers but, if I try use any words it won't work. I need help, thanks!
<?php
if(isset($_POST['teams'])){
$home_team = $_POST['home_team'];
$visitor_team = $_POST['visitor_team'];
$sql = mysql_query("UPDATE table1
SET home_team = $home_team, visitor_team = $visitor_team
WHERE active = 1") ;
$retval = mysql_query( $sql, $conn );
if(! $retval ){
die("<p>Error! Could not update team names. Click return button.</p>");
}
echo "<p>Team names set successfully!</p>";
mysql_close($conn);
}
?>
try with use of '' into your query,
$sql = mysql_query("UPDATE table1 SET
home_team = '".mysql_real_escape_string($home_team)."',
visitor_team = '".mysql_real_escape_string($visitor_team)."'
WHERE active = '1'") ;
also add mysql_real_escape_string() to prevent from SQL Enjection..
Every string passed to a SQL statement must be enclosed within a ''; if they are not, it will result in an error.
That being said, throwing content straight from a form into the database is very, very, very, very (I need another very) bad. Your database can simply be wiped by anyone; it's called SQL injection
To protect your database, you can start with this good article on PDO
So I've been trying to replicate a second order SQL Injection. Here's an example template of two php based sites that I've prepared. Let's just call it a voter registration form. A user can register and then you can check if you're a registered voter or not.
insert.php
<?php
$db_selected = mysql_select_db('canada',$conn);
if (!db_selected)
die("can't use mysql: ". mysql_error());
$sql_statement = "INSERT into canada (UserID,FirstName,LastName,Age,State,Town)
values ('".mysql_real_escape_string($_REQUEST["UserID"])."',
'".mysql_real_escape_string($_REQUEST["FirstName"])."',
'".mysql_real_escape_string($_REQUEST["LastName"])."',
".intval($_REQUEST["Age"]).",
'".mysql_real_escape_string($_REQUEST["State"])."',
'".mysql_real_escape_string($_REQUEST["Town"])."')";
echo "You ran the sql query=".$sql_statement."<br/>";
$qry = mysql_query($sql_statement,$conn) || die (mysql_error());
mysql_close($conn);
Echo "Data inserted successfully";
}
?>
select.php
<?php
$db_selected = mysql_select_db('canada', $conn);
if(!db_selected)
die('Can\'t use mysql:' . mysql_error());
$sql = "SELECT * FROM canada WHERE UserID='".addslashes($_POST["UserID"])."'";
echo "You ran the sql query=".$sql."<br/>";
$result = mysql_query($sql,$conn);
$row=mysql_fetch_row($result);
$sql1 = "SELECT * FROM canada WHERE FirstName = '".$row[1]."'";
echo "The web application ran the sql query internally=" .$sql1. "<br/>";
$result1 = mysql_query($sql1, $conn);
$row1 = mysql_fetch_row($result1);
mysql_close($conn);
echo "<br><b><center>Database Output</center></b><br><br>";
echo "<br>$row1[1] $row1[2] , you are a voter! <br>";
echo "<b>VoterID: $row[0]</b><br>First Name: $row[1]<br>Last Name: $row[2]
<br>Age: $row[3]<br>Town: $row[4]<br>State: $row[5]<br><hr><br>";
}
?>
So I purposely made this vulnerable to show how second order SQL Injection works, a user can type in a code into the first name section (where I am currently stuck, I've tried many different ways but it seems that I can't get it to do anything).
Then when a person wants to activate the code that he has inserted in the first name section, all he needs to do is just type in the userID and the code will be inserted.
For example:
I will type into the insert.php page as:
userid = 17
firstname = (I need to inject something here)
lastname = ..
age = ..
town = ..
state = ..
Then when I check for my details, and type in 17, the SQL script injected will be activated.
Can I get few examples on what sort of vulnerabilities I can show through this?
What is there to demonstrate?
Second order SQL injection is nothing more than SQL injection, but the unsafe code isn't the first line.
So, to demonstrate:
1) Create a SQL injection string that would do something unwanted when executed without escaping.
2) Store that string safely in your DB (with escaping).
3) Let some other piece of your code FETCH that string, and use it elsewhere without escaping.
EDIT: Added some examplecode:
A table:
CREATE TABLE tblUsers (
userId serial PRIMARY KEY,
firstName TEXT
)
Suppose you have some SAFE code like this, receiving firstname from a form:
$firstname = someEscapeFunction($_POST["firstname"]);
$SQL = "INSERT INTO tblUsers (firstname) VALUES ('{$firstname }');";
someConnection->execute($SQL);
So far, so good, assuming that someEscapeFunction() does a fine job. It isn't possible to inject SQL.
If I would send as a value for firstname the following line, you wouldn't mind:
bla'); DELETE FROM tblUsers; //
Now, suppose somebody on the same system wants to transport firstName from tblUsers to tblWhatever, and does that like this:
$userid = 42;
$SQL = "SELECT firstname FROM tblUsers WHERE (userId={$userid})";
$RS = con->fetchAll($SQL);
$firstName = $RS[0]["firstName"];
And then inserts it into tblWhatever without escaping:
$SQL = "INSERT INTO tblWhatever (firstName) VALUES ('{$firstName}');";
Now, if firstname contains some deletecommand it will still be executed.
Using a first name of:
' OR 1 OR '
This will produce a where clause in the second SQL of
WHERE FirstName = '' OR 1 OR ''
Therefore the result will be the first record in the table.
By adding a LIMIT clause, you can extract all rows from the table with:
' OR 1 ORDER BY UserID ASC LIMIT 0, 1 --
Obviously it will only extract 1 row at a time, so you would need to repeat that and increment the 0 in the LIMIT. This example uses a comment -- to terminate the remaining SQL which would otherwise cause the query to fail because it would add a single quote after your LIMIT.
The above is a simple example, a more complex attack would be to use a UNION SELECT which would give you access to the entire DB through the use of information_schema.
Also you are using addslashes() in one of your queries. That is not as secure as mysql_real_escape_string() and in turn: escaping quotes with either is not as secure as using prepared statements or parameterised queries for example in PDO or MySQLi.
After I upload a photo to a server, I want to save it in the user's database in MySQL, but for some reason, it is not working. Below is the code for uploader.php:
session_start();
if(!$_SESSION['userid']) {
header("Location: index.php");
exit;
}
$con = mysql_connect("host","db","pw");
if (!$con)
{
die('Could not connect: ' .mysql_error());
}
mysql_select_db("db", $con);
$sess_userid = mysql_real_escape_string($_SESSION['userid']);
$query = "SELECT * FROM Members WHERE fldID='$sess_userid' UPDATE Members SET PortraitPath = 'profileportraits/' . '$_FILES[file][name]'");
$result = mysql_query($query) or trigger_error(mysql_error().$query);
$row = mysql_fetch_assoc($result);
I'm sure there is something very wrong with my query, but I can't figure out what it is. The photo is definitely being saved into the folder. But I simply want to update its path in the user database for later use. Thank you!
as it was mentioned already, you cannot use these two queries at once.
but there is also weird syntax: you're trying to use PHP's concatenation operator inside of mysql query.
And you did not escape a string parameter - very bad!
So, looks like you need something like
$sess_userid = mysql_real_escape_string($_SESSION['userid']);
$PortraitPath = mysql_real_escape_string('profileportraits/' . $_FILES['file']['name']);
$query = "UPDATE Members SET PortraitPath = '$PortraitPath' WHERE fldID='$sess_userid'";
You can do two separate queries:
UPDATE Members SET PortraitPath = 'profileportraits/' . '$_FILES[file][name]'
WHERE fldID='$sess_userid';
And:
SELECT * FROM Members WHERE fldID='$sess_userid'
It seems you tried to put two queries(SELECT and UPDATE) into one query which will result in invalid query error.
Just wondering why you need two queries since you already know the userid and all you want is to update. All you need is to update the file path
UPDATE Members SET PortraitPath = 'profileportraits/' . '$_FILES[file][name]' WHERE fldID='$sess_userid';
Hey, I wrote some code for extracting some information out of the database and checking to see if it met the $_COOKIE data. But I am getting the error message:
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
My code so far is:
$con = mysql_connect("XXXX","XXXXX","XXXXXXX");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("XXXXXX", $con);
$id = $_COOKIE['id'];
$ends = $_COOKIE['ends'];
$userid = strtolower($_SESSION['username']);
$queryString = $_GET['information_from_http_address'];
$query = "SELECT * FROM XXXXX";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
if ($queryString == $row["orderid"]){
$sql="UPDATE members SET orderid = ''WHERE (id = $id)";
$sql="UPDATE members SET level = 'X'WHERE (id = $id)";
$sql="UPDATE members SET payment = 'XXXX'WHERE (id = $id)";
$sql="UPDATE members SET ends = '$ends'WHERE (id = $id)";
if (!mysql_query($sql))
{
die('Error: ' . mysql_error());
}
}
}
Any help would be appreciated,
Thanks.
$sql="UPDATE members SET ends = '$ends'WHERE (id = $id)";
should be
$sql="UPDATE members SET ends = '$ends'WHERE (id = '$id')";
(IE add the ' around $id)
I'm not sure if this is the error, but do you realize you're code only runs the last UPDATE? You're assigning $sql 4 time, and only running it after the fourth assignement...
If $_COOKIE['id'] does not have a value, then $id in your SQL statements will be blank, leaving your SQL looking like this:
UPDATE members SET ends = 'something' WHERE (id = )
which, of course, is invalid SQL.
Only one of the SQL statements will execute, and that's the last one. You need to add some whitespace before the WHERE clause, like this:
$sql="UPDATE members SET ends = '$ends' WHERE (id = $id)";
Also be wary of SQL injection attacks in the event that your cookie is altered by the end user. One other thing of note is your orderid column. Is it a VARCHAR or some other unique identifier? If it's an integer, then setting it to empty string will not work. You might want to rethink your schema a bit here.
EDIT: Another thing you need to do is check to make sure the cookies actually have values. If not, your SQL strings will be messed up. Have you though about using parameterized queries through PDO so you don't have to worry about SQL injection at all?
first of all you keep overwriting $sql variable so only the
$sql="UPDATE members SET ends = '$ends'WHERE (id = $id)";
is being executed.
And I would say that $id variable is not what you think it is (maybe empty as query like the one above without id:
$sql="UPDATE members SET ends = '$ends'WHERE (id = )";
would throw such error back.
Try
$id = NULL;
before
$id = $_COOKIE['id'];
if the error is gone that means that $id is not what you think it is