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!
Related
Thank you first of all for coming to try and help me solve an issue I am having with my current attempt to build a customer user system.
First of all, a brief explanation on the system I am trying to build might shed some light on the meaning behind my approach.
I am trying to build a system where the user can log into the website via the WordPress Login & Registration System, but then, based on their WordPress ID, they'll be given information related to that ID from another MySQL Table.
The reason for this is, we want to store specific data to users on another table, such as Weight, Height, Sex, and more.
The reason this needs to be in another table, is that an API from another service will directly put the data (and keep it up to date) in a specific table we will create.
The Code:
$servername = 'server';
$username = 'username';
$password = 'password';
$conn = mysql_connect($servername, $username, $password);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
$sql = 'SELECT pacientes.Id, wp_users.ID, pacientes.nombre
FROM pacientes
RIGHT JOIN wp_users
ON pacientes.Id = wp_users.ID';
mysql_select_db('database');
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
die('Could not get data: ' . mysql_error());
}
echo "Fetched data successfully";
mysql_close($conn);
Up until this point, everything seems to work as intended. I am given the all clear by all the die commands, and so I don't suspect there is any issue with finding, or locating the database, and tables I've mentioned.
The Code (Part 2)
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
echo "WordPress ID: {$row['ID']} <br> ".
"Patient Id: {$row['ID']} <br> ".
"Patient First Name: : {$row['nombre']} <br> ".
"Patient Second Name : {$row['apellidos']} <br> ";
}
Now, this is echoing the data correctly. As you can see the Patient ID & WordPress ID are correctly associated with each other. The 4th user in the Patient Table is indeed Manuel.
You can see a quick screenshot here: https://gyazo.com/300af05da9afc8bcffa8f7efac628691
So my issue is with making this system only pull the data from the Patient Table, that is related to the ID of the current user, as chosen by the WordPress User ID.
I've looked at various sources that I will also link below, but none have so far produced what I am attempting to create.
Again; The intention here is that the user can log in using WordPress, and based off their WordPress ID co-inciding with an ID in the Patient Table, they should be shown their own specific data from the Patient Table, based on their ID's matching in both tables.
Current Research:
Integrating wordpress authentication with an existing user database
getting specific data from wordpress database table
Get the data of specific user in PHP
I greatly appreciate any help, advice or guides you can provide me with. Thank you.
So, after a little more work I found the solution
Code (Database Connection & SQL Queries)
$servername = 'YourServer';
$username = 'YourUsername';
$password = 'YourPassword';
$conn = mysql_connect($servername, $username, $password);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
// Get the current User ID of the person logged into WordPress.
$currentUser = get_current_user_id();
$sql = 'SELECT wp_users.ID, sharedID, pacientes.nombre, pacientes.peso
FROM pacientes
RIGHT JOIN wp_users
ON pacientes.Id = wp_users.ID';
mysql_select_db('Sql918293_2');
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
die('Could not get data: ' . mysql_error());
}
echo "Fetched data successfully";
mysql_close($conn);
Those code pulls all the relevant data from the databases, and joins them together so that you can use both tables, as long as they have a common ID. In this instance, the ID of the WordPress user needs to match the ID in the patient table.
Code (Echo the Data only to the relevant user)
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
if ($row['Id'] == $currentUser)
{
echo
"WordPress ID: {$row['ID']} <br> ".
"Patient Id: {$row['Id']} <br> ".
"Patient First Name: : {$row['nombre']} <br> ".
"Patient Second Name : {$row['apellidos']} <br> ".
"----------------------------------------<br>";
}
}
The fix was actually really easy, and I have no idea why it pop into my head before. All I had to do was apply the $currentUser = get_current_user_ID(); to grab the ID from WordPress, and put it into a variable.
Then I did a simple If Statement to check against, and only to echo the information if the variable was correct.
if ($row['Id'] == $currentUser)
This basically checks against the ID (Patient ID) as seen above, and if it equals the same as the current user (As you're already logged into WordPress), then print the information.
I hope this helps everyone!
Hey guys I am new to programming and I have a quick question and hopefully it isnt too much. I am trying to give users of my test website to have the ability to update their information. I use the following code:
$mysqli = mysqli_connect('localhost', 'root', 'testpass', 'testdatabase')
or die(mysqli_error());
echo "<h2>How would you like to update your account $_SESSION[username]?</h2>";
$display = <<<END
<h4> Update your username here: <br/></h4>
<form method="POST" action="$_SERVER[PHP_SELF]">
<input type="text" name="update_username"/>
<input type="submit" name="submit" value="Update"/>
</form>
END;
echo $display;
$update_username = $_POST['update_username'];
$current_username = $_SESSION['username'];
$sql_update = "UPDATE users SET username = '$update_username' WHERE username = '$current_username'";
$result_update = mysqli_query($mysqli, $sql_update) or die (mysqli_error($mysqli));
The code above updates their information, but it only updates once. When I check the database after updating it, it changed to whatever I changed it too. Then I try and changed it again but it doesnt change, so I log out and log back in. When I log back in I change it, but this time, when I look at the database, there is no username. I log back out and log back in again. I change it again and it actually changes. I have to go through this same process everytime I try and change the username(or any other sort of information) and it gets very annoying. Do you guys have any ideas on why it is doing this?Thanks!
For database stuff, you want to track everything by IDs, so the first field in most every table will be 'id', set as primary key with auto increment. Then when updating you would do WHERE id = $userID. When they login, the user id would be stored in the session as well as username, and any queries would reference them by id. It also makes it a lot easier/faster to query/track stuff when you start doing table joins
try the following
END;
echo $display;
$update_username = $_POST['update_username'];
$current_username = $_SESSION['username'];
$current_id = mysql query select id where username = $current_username
$sql_update = "UPDATE users SET username = '$update_username' WHERE id = '$current_id'";
$result_update = mysqli_query($mysqli, $sql_update) or die (mysqli_error($mysqli));
hope you can fix my pseudo code in $current_id variable
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.
I've been modifying my code but I still can't log in... I have a MySQL database with a database called "users" with a table called "Users" and the following rows "UserNameID", "userName" and "password". I have created just an entry in order to test that:
+------------+----------+-----------+
| UserNameID | userName | password |
+------------+----------+-----------+
| 1 | root | pass |
+------------+----------+-----------+
Here my code:
<!DOCTYPE html>
<?php session_start(); ?>
<html>
<head>
<title>File1</title>
</head>
<body>
<?php
$DB_connection = mysqli_connect("localhost","user1","user1","users") or die("ERROR. Failed to connect to MySQL." . mysqli_error($DB_connection));
function SignIn() {
$usr = $_POST['user'];
$pw = $_POST['pwd'];
if(!empty($usr)) {
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
$result = mysqli_query($DB_connection,$query);
if($result) {
while($row = mysqli_fetch_array($result)) {
echo "SUCCESSFULLY LOGIN TO USER PROFILE PAGE..."; }
} else {
echo "SORRY... YOU ENTERD WRONG ID AND PASSWORD... PLEASE RETRY..."; } }
}
SignIn();
mysqli_close($DB_connection);
?>
</body>
</html>
When I introduce a wrong password or username, it gives me "SORRY... YOU ENTERD WRONG ID AND PASSWORD... PLEASE RETRY...". However, it throws me the same when I put the correct password and username. What is wrong in my code?
Thanks a lot!
There numerous issues here. There are scoping issues, you are using the wrong methods, it's unsafe.
First off, these 2 lines:
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
$result = mysqli_query($DB_connection,$query);
That's not how you query a database. You only need to call either mysql_query or mysqli_query depending on what API you are using. You are using MySQLi in this case, so do this:
$query = "SELECT * FROM Users where userName = '$usr' AND password = '$pw'";
$result = mysqli_query($DB_connection,$query);
Second, your SignIn function can't access the $DB_connection variable, it's out of scope. You need to pass it in:
function SignIn($DB_connection){
}
SignIn($DB_connection);
Third, this code is very unsafe! Never use $_POST directly in an SQL query like that. You should never be concatenating variables into an SQL string, you should use prepared statements.
// Don't use "SELECT *", use the fields you want
$query = mysqli_prepare($DB_connection, 'SELECT user_id FROM Users where userName = ? AND password = ?');
// This sends the values separately, so SQL injection is a thing of the past
mysqli_stmt_bind_param($query, 'ss', $usr, $pw);
// Run the query
mysqli_stmt_execute($query);
// Prepared statements require to define exactly the fields you want
mysqli_stmt_bind_result($query, $user_id);
// Get the data
while(mysqli_stmt_fetch($query)){
echo $user_id;
}
mysqli_stmt_close($query);
Lastly, storing plaintext passwords is bad practice. Use a hashing library. PHP 5.5+ has one built-in (http://php.net/password). There's also a version for lesser PHP versions (https://github.com/ircmaxell/password_compat).
P.S. As pointed out in the comments (here's a link), your session_start() is in the wrong spot. That sends a header, so it requires that there be nothing echoed out before it.
<?php session_start(); ?>
<!DOCTYPE html>
<html>
Make sure that there is no whitespace (or anything) before the session_start().
Your problem is here:
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
This should instead be
$query = "SELECT * FROM Users where userName = '$usr' AND password = '$pw'";
You're then passing the query string rather than a resource to mysqli_query.
(Also, refer to Shankar Damodaran's answer regarding the scope issue: pass $DB_connection to the SignIn function).
As a side note, you shouldn't use posted data directly into the query. You're at risk of SQL injection. Look into sanitizing the data or, preferably, prepared statements.
First of all, you are running into scope issues here.
In this line...
$result = mysqli_query($DB_connection,$query);
The variable $DB_connection is not accessible inside your SignIn() and thus your query is getting failed. Also you are mixing mysql_* (deprecated) functions with mysqli_* functions.
This simple and small code snippet for the login might help you..
$con = mysqli_connect("localhost","user1","user1","users") or die("ERROR. Failed to connect to MySQL." . mysqli_error($con));
$username = $_POST['username'];
$password = $_POST['userpassword'];
$result = mysqli_query($con,"SELECT * FROM users WHERE user_name = '$username' and user_password='$password'");
$count=mysqli_num_rows($result); // get total number of rows fetched. needs only 1 row for successful login.
if($count==1){
//Login successful
}
else{
//Login unsuccessful
}
It will fetch a row if the entered username and password are matched.It will fetch only one row as the username and password will be unique. If the count of rows fetched is '1' you can have successful login.
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.