I am trying to enable users to change their password.
I keep getting the user name and password are not in the file and I suspect the password is not correctly readable by the script, maybe because of the md5 encryption. Is there any error on my SQL query?
$query = "SELECT * FROM users WHERE name='$e' AND pass='".md5($p)."'";
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
$num = mysql_num_rows($result);
Instead of building up your query with concatenation, you should look into using PHP Data Objects (PDO).
Not only will it likely fix your error, it will also fix your current Sql Injection vulnerability.
Related
Context
I'm trying to implement a (hopefully) simple login system using PHP and PostgreSQL.
This is the postgres table containing usernames and hashed passwords.
Users are not meant to be able to create new rows in this table so I already hashed the passwords using password_hash('password', PASSWORD_BCRYPT) and then manually copypasted the value in the table.
Let me know if you think this could pose a problem.
Users can, however, login to an already existing account by inputting the right username and password combination into a login form.
When the login button is pressed I need to retrieve information about the user entered, so that if it matches any user I can then verify the password using password_verify().
The Problem
When the login button is clicked I run this code:
$dbconn = pg_connect("host=host dbname=dbname user=user password=pwd");
if (!$dbconn) {
die("Error in connection: " . pg_last_error());
}
// setting the username as it would be provided by the form field
$username = 'Dan';
// maybe unrelated: why do I need to write 'username' instead of username? all of my other queries work without ''
$query = "SELECT * FROM user WHERE 'username' = $1";
$stmt = pg_prepare($dbconn, "", $query);
var_dump($stmt); // gives output "resource(3) of type (pgsql result)", got no clue on how to see what's indside
$result = pg_execute($dbconn, "", array($username));
var_dump($result); // gives output "resource(4) of type (pgsql result)"
$row = pg_fetch_assoc($result);
var_dump($row); // gives output "bool(false)", indicating that pg_fetch_assoc() failed
The main problem would be that pg_fetch_assoc() fails and returns false, however I believe this may also be caused by an incorrect query or by the way I build the statement, hence why I included everything.
Edit
Forgot to mention that I also tried formulating the query as:
$query = "SELECT * FROM user WHERE username = $1";
And in this case I get and error saying:
Warning: pg_prepare(): Query failed: ERROR: column "username" does not exist LINE 1: SELECT * FROM user WHERE username = $1.
Thanks to Don't Panic's comment I renamed my user table to utiliser and everything worked as it should have.
It should also be noted that this could be circumvented by using double quotes on the table name (according to this answer), however, double quotes are evil so better to just stay away.
Here's the full table of reserved words to avoid as table/column names.
so, I'm using one query to get the profile photo, i'm using the follow query:
$sql = "SELECT photo FROM users WHERE login = '$username'";
I already tried many ways to do, with and without the inverted commas.
$sql = "SELECT `photo` FROM `users` WHERE `login` = '$username'";
Next code is like:
$result = mysqli_query($link, $sql);
echo "<script>console.log('photo: ".$sql."');</script>";
When I check the console i see this error:
Uncaught SyntaxError: missing ) after argument list
When I do the query with just "select photo from users" it returns a value.
On another page I use the same code to get the permissions and it returns a value that I want
$sql = "SELECT permission FROM users where login = '$username'";
$result = mysqli_query($link, $sql);
if ($result->num_rows > 0) {
while ($row = mysqli_fetch_array($result)) {
$save = $row[0];
}
}
Permission Column is int;
Photo Column is varchar;
Since the query contains single quotes, you can't use single quotes around the argument to console.log(), because the quote in the query will terminate the JavaScript string.
Put double quotes around the JS string.
echo "<script>console.log(\"photo: ".$sql."\");</script>";
Your javascript console is wrapped in ' quotes, and your '$username' value is also using these single quotes so this is causing a problem.
Therefore; if you want to export this SQL string to your console, you need to escape these single quotes or to use alternative quotes in your javascript.
This issue is better resolved by Barmar's Answer.
BUT:
Best Practise; you should NOT be outputting SQL strings to your browser at all. This is a potentially severe security hole. Instead (especailly if your SQL server is 'localhost') you should be outputting your SQL data to your PHP error logs:
$result = mysqli_query($link, $sql);
//echo "<script>console.log('photo: ".$sql."');</script>";
error_log("Query Output: ".print_r($sql,true));
Then in your IDE or secured server connection (SFTP etc.) then you can access the PHP Error Logs and view the SQL more safely.
See also: Where does PHP store the error log? (php5, apache, fastcgi, cpanel)
I wrote a SQL query for checking name in php, but it does not work.
I have no assumptions how to fix it, but I assume it's just mistake in syntax.
$username = $_POST["username"];
$nameCheckQuery = "SELECT username FROM users WHERE username '" . $username . "';";
$nameCheck = mysqli_query($db, $nameCheckQuery) or die("2: Name check query failed");
I receive error log on query.
The reason it's failing is likely due to you missing a = after username.
This code is open to SQL injection and you should use prepared statements.
The most basic of a prepared statement looks something like this:
$stmt = $db->prepare("SELECT * FROM users WHERE username = ?");
$username = $_POST['username'];
$stmt->bind_param('s', $username);
$result = $stmt->execute();
The main problem of your query is that you forget to insert = next to WHERE username.
You have to write:
$nameCheckQuery = "SELECT username FROM users WHERE username ='" . $username . "';";
Right now it works but......
The query you are using is not preventing a SQL INJECTION attack (one of the most used attack against database).
Please take a look at the ways you can connect to the database:
use PDO (it works with 12 database type);
use MSQLI (it works only with MYSQL database and you are using it);
In other word, if you are planning that you will move your application in another database type please consider to use PDO, instead.
Using PDO preventing SQL injection you have to prepare the SQL statement like this:
$stmt = $pdo->prepare("SELECT username FROM users WHERE username = ?");
$stmt->execute([$_POST['username']]);
$arr = $stmt->fetch();
For Starter, please use this escape string:
$username = $mysqli->real_escape_string($_POST["username"]);
Simply do it like this and don't get confused with quotes.
You can still print php variables inside single quote like this.
$nameCheckQuery = "SELECT username FROM users WHERE username = '$username'";
or to edit your code, this is how you can achieve it.
$nameCheckQuery = "SELECT username FROM users WHERE username ='" . $username."'";
Just to answer your question, it is Vulnerable to Sql Injection.
Reasons why Sql Injection occurs:
SQL Injection occurs when an attacker is able to send their own instructions to your database and the database executes those instructions. This occurs when a PHP developer has taken input from a website visitor and passed it to the database without checking to see if it contains anything malicious or bothering to clean out any malicious code.
SQL Injection can allow an attacker to access all of your website data. They can also create new data in your database which may include links to malicious or spam websites. An attacker may also be able to use SQL Injection to create a new administrative level user account which they can then use to sign-into your website and gain full access.
SQLi is a serious vulnerability because it is easy to exploit and often grants full access immediately.
This is how you can achieve it, which provides detailed functionality.
https://stackoverflow.com/a/60496/6662773
I am trying to login with email or mobile (in PHP and MySQL). But I am unable to login.
Here is my code:
$sql = "SELECT * FROM tb_users WHERE (email='$loginEmailOrMobile' AND password='$loginPassword') OR (mobile_number='$loginEmailOrMobile' AND password='$loginPassword')";
$mysql = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($mysql) == 1)
{
echo "login successful";
$user = mysql_fetch_object($mysql);
echo $user->username;
}
else
{
die(mysql_error());
}
I think you have many problems in your code.
The mysql* extension is deprecated, and removed in PHP 7.
Plain passwords have poor security.
Prepared statements are recommanded when using variables.
You are handling an error when there is not.
You probably have no row (or more that 1) matching with your credentials so it's neither a success nor a MySQL error.
I will not cover all of this points in this answer in order to respect your original code, but I will try to explain many of them.
First, there is a tested and working code that does the job.
<?php
//Connect to the database
$mysqli = new mysqli("localhost", "username", "password", "databaseName");
//These variables may be set from $_POST or anywhere
//it is only an example
$loginEmailOrMobile = 'an-email#example.com';
$loginPassword = '123456';
//!!Vulnerable to SQL injections**
$sql = "SELECT * FROM tb_users WHERE password = '$loginPassword' AND (email='$loginEmailOrMobile' OR mobile_number = '$loginEmailOrMobile')";
$result = $mysqli->query($sql);
//Only if we got 1 result
if (1 === mysqli_num_rows($result)) {
$user = mysqli_fetch_object($result);
echo $user->email;
} else {
die('We have not got only one result');
}
In this code you can see that:
Mysqli is used to perform the queries. It's really recommended to use mysqli instead of mysql for security reasons. Also, I'm using PHP 7 and I have not the mysql extension.
Because the case you were handling with mysql_error() was not en error, I have removed it in order to handling the case. If I get 0, or even 2 results, that's not a MySQL error, but perhaps I have no user or more than 1 with that credentials.
I have updated your SQL query in order to be less redundant but the logic is the same.
Your SQL query is not a prepared statement, I haven't touch it in order to respect your code and not to rewrite it entirely. But I really advise you to have a look at mysqli prepared statements
It seems you are currently using a plain password (unless you have already hashed it). It is recommanded to hash your passwords before inserting them into the database, and compare only the hashes. Please have a look to crypt().
I can't figure out why my SQL select query keeps failing - I am new to SQL so it might b a stupid mistake but I have not been able to find the answer in the documentation. Thanks a lot in advance
// connect to db
$mysqli = new mysqli("127.0.0.1", "maok08ab", "", "Portfolio");
if ($mysqli->connect_errno)
{
echo "Failed to connect to MySQL";
}
$username=$_POST["username"];
$email=$_POST["email"];
$hash=$_POST["password"];
$query = "SELECT * FROM users WHERE username = '$username'";
$result= mysqli_query($mysqli, $query);
if ($result == FALSE)
{
apologize("something went wrong");
}
Since you're using an OOP connection you have to use OOP to perform the query:
$query = "SELECT * FROM users WHERE username = '$username'";
$result = $mysqli->query($query);
It states very clearly in the manual:
Link Procedural style only: A link identifier returned by mysqli_connect() or mysqli_init()
So your use of $result= mysqli_query($mysqli, $query); will not work as you would think. Make sure to stick with one method (OOP or procedural) throughout the life of your code.
In addition:
Learn about prepared statements for MySQLi. Even escaping the string is not safe! Don't believe it?
Never store plain text passwords! Please use PHP's built-in functions to handle password security. If you're using a PHP version less than 5.5 you can use the password_hash() compatibility pack. Make sure you don't escape passwords or use any other cleansing mechanism on them before hashing. Doing so changes the password and causes unnecessary additional coding.