I'm wondering how I can make this code safer, I'm using it as login.php:
if(isset($_POST["username"]) and isset($_POST["password"])) {
if($_POST["username"] == $adminusr && $_POST["password"] == $adminpass){
I want to make it a little more safe to prevent sql-injections and such. Do you have any ideas ? I'd like to learn more about making safer sites.
Thank you dudes and dudettes
Edit:
Sorry I didn't post all the code needed, but here is the complete code:
<?php
session_start();
include_once("../include/config.php");
if(isset($_POST["username"]) and isset($_POST["password"])) {
if($_POST["username"] == $adminusr && $_POST["password"] == $adminpass){
$_SESSION['admin_user'] = $adminusr;
$_SESSION['admin_password'] = $adminpass;
}
else {
echo "Wrong Username or Password";
}
}else if(isset($_GET['act']) && $_GET['act']=='out') {
unset($_SESSION['admin_user']);
unset($_SESSION['admin_password']);
session_destroy ();
}
if($_SESSION['admin_user'] == $adminusr && $_SESSION['admin_password'] == $adminpass){
$_SESSION['testdd'] = 'test';
header("location:index.php");
exit;
}
?>
Thank you once again :)
If you are using $_POST['username'] in a query the following code will keep you save from SQL-injection.
$username = mysql_real_escape_string($_POST["username"]);
$password = mysql_real_escape_string($_POST["password"]);
$query = "SELECT * FROM users
WHERE users.username = '$username'
AND users.Passhash = SHA2(CONCAT(users.id,'$password'),512) ";
$result = mysql_query($query);
....
Note that you need to use mysql_real_escape_string() with mysql_query
and mysqli_real_escape_string() with mysqli_query.
Even better is to use PDO with php5, see: http://www.php.net/manual/en/book.pdo.php
Handling passwords in MySQL
Note that is strongly recommended not to store passwords in the clear in your database.
Always store a hash (preferably using SHA2) in your database and use a salt.
See: https://stackoverflow.com/search?q=hash+salt+mysql
For more info on this.
I think you code should be like this:
if(isset($_POST["username"]) and isset($_POST["password"])) {
$handle = mysql_connect($host, $user, $pass);
mtsql_select_db($db, $handle);
$query = "SELECT user FROM table_users WHERE user='{$_POST["username"]}' AND password=MD5('{$_POST["password"]}')";
$result = mysql_query($query, $handle);
if(mysql_num_rows($result) == 1)
{
What you need here is to escape special charcarter using mysql_real_escape_string() or PDO prepared statement, so we change this:
$input["user"] = mysql_real_escape_string($_POST["username"]);
$input["password"] = mysql_real_escape_string($_POST["password"]);
$query = "SELECT user FROM table_users WHERE user='{$input["user"]}' AND password=MD5('{$input["password"]}')";
.
.
.
You may also use addslashes() function, but it may be sufficient enough, I am quoting from this:
addslashes adds slashes to characters
that are commonly disturbing.
mysql_real_escape_string escapes
whatever MySQL needs to be escaped.
This may be more or less characters
than what addslashes takes care of.
You should use mysqli_real_escape_string to escape special characters (assuming you are querying database). E.g. $password = mysqli_real_escape_string($link, $_POST['password']);. Otherwise, it seems fine.
Your code doesn't show what you are actually doing with the database.
If you use a regular mysql_query, you need to encode unwanted characters, quotes (",') for example.
You also need to keep in mind, that people might want these characters in their passwords, so you need to store them in the DB encoded in some way.
Probably an MD5 hash, or just regular entity encoding (see below).
htmlentities($pass,ENT_QUOTES,'UTF-8')
(!get_magic_quotes_gpc()) ? mysql_real_escape_string($item):$item;
You should still use variable binding, that helps avoiding any SQL injections.
Check out this introduction to PDO, its really useful.
Related
Wampserver. in phpmyadmin i have added users db and user_data table. but my code doesn't work
<?php
include_once("sql_connect.php");
session_start();
$_SESSION['currentuser']=$_POST['usernameinput'];
$uname = $_POST['usernameinput'];
$pass = $_POST['passwordinput'];
$sql = "SELECT * FROM 'user_data' WHERE(
username='".$uname."' and password='".$pass."')";
$query = mysql_query($sql);
$result = mysql_fetch_array($query);
if($result[0]>0)
{
header ("location: Ghome.php");
}
else
{
header ("Location: loginform_er_incorrectlogpass.php");
}
?>
When i wrote correct username and password it doesn't work. maybe something wrong with my code?
<?php
session_start(); # Starts the session
session_unset(); #removes all the variables in the session
session_destroy(); #destroys the session
include ("LoginForm.php");
echo "<p align='center'><font color='red'>Неправильно указан Логин или Пароль.</font></p>";
?>
To fix your current problem, remove the quotes around the table name and get used to using back ticks instead.
SELECT * FROM `user_data` ...
Not this:
SELECT * FROM 'user_data' ...
(Technically, you don't even need the back ticks here, but using them is a good practice and will help catch a variety of typos down the road.)
Some additional pointers:
Never store passwords as plain text; this is extremely bad security practice. Use hashing and salting. Specifically, use bcrypt.
Please don't use mysql_*; the mysql_* functions are outdated, deprecated, and insecure. Use MySQLi or PDO instead.
You are wide open to SQL injection.
You were incorrectly using single quotes around the table name in your sql - you should use backticks instead. Also, there was no check for POSTed variables. Ideally though, to avoid heartache in the future, look at migrating to use either mysqli or PDO. At the very least try some basic filtering of provided POST data
<?php
session_start();
include_once("sql_connect.php");
if( isset( $_POST['usernameinput'] ) && isset( $_POST['passwordinput'] ) ){
$uname = mysql_real_escape_string( $_POST['usernameinput'] );
$pass = mysql_real_escape_string( $_POST['passwordinput'] );
$_SESSION['currentuser']=$uname;
$sql = "SELECT * FROM `user_data` WHERE `username`='".$uname."' and `password`='".$pass."';";
$query = mysql_query( $sql );
$result = mysql_fetch_array( $query );
header('location: ' .( $result[0]>0 ) ? 'Ghome.php' : 'loginform_er_incorrectlogpass.php' );
}
?>
replace this
$query = mysql_query($sql)
with the following
$query = mysql_query($sql) or die(mysql_error());
and see what error you are getting
Before you say it: I know the passwords should be encrypted/hashed, but I want to get this down first:
I have this login function and a SQL database. However, the login function doesn't seem to work and I haven't the faintest idea why. I am probably missing something stupid, but have been struggling with this for a while now. Any help would be appreciated!
NOTE: the file db_connect.php is really just a basic connecting to the database, nothing wrong there
FUNCTION.PHP:
<?
function login($username, $password, $con)
{
$myQuery = "SELECT * FROM Members WHERE Username = '$username' and Password = '$password';";
$result = mysqli_query($con, $myQuery);
if (mysql_num_rows($result) == 0)
{
return false;
}
else
{
return true;
}
}
?>
PROCESS-LOGIN.PHP:
<?php
include 'db_connect.php';
include 'functions.php';
if (isset($_POST['username'], $_POST['pword'])) {
$username = $_POST['username'];
$password = $_POST['pword']; // The hashed password.
if (login($username, $password) == true) {
// Login success
header('Location: welcome.html');
}
else
{
// Login failed
header('Location: index.html');
}
}
else {
// The correct POST variables were not sent to this page.
echo 'Invalid Request';
}
?>
You are not providing the $con parameter to login function.
function login($username, $password, $con)
You are calling it as
login($username, $password)
Try providing the connection argument to see if it works.
Also note the answer kingkero made. You are using functions from different libraries.
Some things I noticed
Are you using method="POST" in your form?
Your SQL query is vulnerable to SQL injections
your mixing mysql_* with mysqli_* functions
missing $con parameter for login function
You are mixing MySQLi (mysqli_query) with MySQL (mysql_num_rows) - decide for either one (preferably the former).
If you are using MySQL, the parameters for mysql_query are in wrong order.
In addition to that you are failing to pass the connection to the login as a parameter (as WoLfulus mentioned).
Some additional info as you seem to be learning:
The return statement of login can be simplified to return mysql_num_rows($result) == 1;. This will return TRUE if one record was found and FALSE otherwise - no need for an if/else statement here, you already have the logic you need.
Right now anyone can access welcome.html without logging in by simply typing the address in the browser. This can be avoided by using sessions.
Since you don't properly escape the user input (which one should never trust!), you are vulnerable to SQL injections. mysql_real_escape_string is a start but no 100% solution. If you used prepared statements on the other hand, you wouldn't need to worry.
I'm answering since I don't have enough reputation to comment your question.. But you should keep your variables outside the quotes and add mysql_real_escape_string() to prevent mysql injection..
$myQuery = "SELECT * FROM Members WHERE Username = '$username' and Password = '$password';";
Should be:
$myQuery = "SELECT * FROM Members WHERE Username = '". mysql_real_escape_string($username) ."' and Password = '". mysql_real_escape_string($password) ."';";
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
I have problem with my login form sql injection is working on it so how to stop it.
I am using mysql_real_escape_string but nothing changed
if(isset($_POST['submit-login'])) {
$user = $_POST['username'];
$pass = $_POST['password'];
$username = mysql_real_escape_string($user);
$password = mysql_real_escape_string($pass);
$usertool = new Usertool();
if($usertool->login($username, $password)){
//successful login, redirect them to a page
header("Location: index.php");
}else{
$error = "Incorrect username or password. Please try again.";
}
}
Here is usertool
class usertool {
public function login($username, $password) {
$hashedPassword = md5($password);
$result = mysql_query("SELECT * FROM tbl_user WHERE uname = '$username' OR eemail = '$username' AND password = '$hashedPassword'");
if (mysql_num_rows($result) == 1) {
$_SESSION["user"] = serialize(new User(mysql_fetch_assoc($result)));
$_SESSION["login_time"] = time();
$_SESSION["logged_in"] = 1;
return true;
} else {
return false;
}
}
it is not a classic SQL injection in your case but rather wrong SQL logic.
You need to add braces to your query:
SELECT * FROM tbl_user
WHERE (uname = '$username' OR eemail = '$username')
AND password = '$hashedPassword'"
In your original query the whole statement evaluates to true if entered username or email matches, and password not even being checked
And regarding SQL injections in general, to make your queries safe, you have to format your query parts according to these rules
Formatting have to be complete. mysql_real_escape_string does incomplete formatting alone: you ought to add apostrophes around whatever data you escaped using this function.
Formatting have to be adequate, means you can't format a number or an identifier with string formatting. EVery SQL literal require it's own distinct formatting.
Formatting have to be done as close to the query execution as possible.
Following these rules you'll be pretty safe from injection. And using prepared statements is the easiest way to follow them.
One don't need neither mysqli not PDO to use native prepared statements though - you can create your own variant. But nevertheless, you have to move mysql_real_escape_string as closer to the query execution as possible and always add apostrophes around the result.
Having searched thoroughly through my code, the only reason that I could determine for this error is that the technique I am using for converting the string to MD5 is invalid. However I cannot find another way to do so.
$username = $_POST['username'];
$password = $_POST['password'];
$repassword = $_POST['repassword'];
if( $password=$repassword ) {
$con=mysql_connect("localhost", "root", "");
if( $con == true ) {
mysql_select_db("movedb", $con);
//$newpassword = mysql_real_escape_string(md5($_POST['password']));
$query = "UPDATE user SET password=MD5('$password') WHERE username='$username'";
// $query = "UPDATE user SET password='$newpassword' WHERE username='$username'";
$result = mysql_query($query, $con);
if( $result == true ) {
echo "Successfully saved your message";
} else {
echo mysql_error();
}
mysql_close($con);
} else {
echo "Cannot connect to the database";
}
} else {
echo "Passwords do not match!";
}
Any ideas on how to update this MD5 value from PHP
$password = md5($password);
$query = "UPDATE user SET password='".$password."' WHERE username='".$username."'";
Use PHP supported md5 hash.
An issue that can cause problems is that MySQL and PHP use different default salts when they encrypt. This means that the resulting strings will be different. So you have to use either PHP or MySQL to encrypt and not a mixture of the 2.
Secondly, MD5 has been superceded by other better encryption algorithms. You might consider using one of those for improved security. Check out PHP's crypt() function.
To check the password:
SELECT * FROM 'user' WHERE username='bob.jhonny' AND pass=MD5('oldPassword');
To update:
UPDATE 'dlp_contatcs'.'user' SET 'Pass'=MD5('NewPassword') WHERE 'Username'='bob.jhonny';
Warning:
Please, don't use mysql_* functions to write new code. They are no longer maintained and the community has begun the deprecation process. See the red box?
Instead, you should learn about prepared statements and use either PDO or MySQLi. This article should give some details about deciding which API to use. For PDO, here is a good tutorial.
You can calculate the md5() hash with PHP and store it into a variable, then put that variable into the database. Just make sure you do the same conversion (md5 in the PHP code body) when checking against the database.
You should fix the line if( $password=$repassword ). You need either two or three = signs to make the if check against something. The proper line would be if( $password === $repassword ).
// ...
$newpassword = md5($_POST['password']);
$result = mysql_query('UPDATE user SET password="' .mysql_real_escape_string($newpassword). '" WHERE username = "' .mysql_real_escape_string($username). '"', $con);
if ( $result === TRUE )
{
echo "Successfully saved your message.";
// ...
Can you experts give me some thougths on this code? Some security hole i have missed?
Can you see any potential threats? Something i can do better?
I'm still learning :) Thanks
<?php
if (isset($_POST['username'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$password2 = mysql_real_escape_string($_POST['password2']);
$encrypted_password = md5($password);
// remove eventuakl space
foreach($_POST as $key => $val) $_POST[$key] = trim($val);
// check if username is taken
$query = mysql_query("SELECT COUNT(*) FROM users WHERE username = '$username'");
if (mysql_result($query, 0) > 0) {
$reg_error[] = 0;
}
// make sure username only cosist of at least 3 letters, numbers or _ -
if (!preg_match('/^[a-zA-Z0-9_-]{3,}$/', $username)) {
$reg_error[] = 4;
}
// check for empty fields
if (empty($username) || empty($password) || empty($password2)) {
$reg_error[] = 2;
}
// check if the passwords match
if ($password != $password2) {
$reg_error[] = 3;
}
// save if error is unset
if (!isset($reg_error)) {
mysql_query("INSERT INTO users (username, password, registered, registration_ip)
VALUES('$username', '$encrypted_password', '".time()."', '".$_SERVER['SERVER_ADDR']."')");
$_SESSION['id'] = mysql_insert_id();
header('refresh: 3; url=/home');
}
}
?>
Login.php
if (isset($_POST['username'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$md5_password = md5($password);
$query = mysql_query("SELECT id FROM users WHERE username = '$username' and password = '$md5_password'");
if (mysql_num_rows($query) == 0) {
header("Location: ".$_SERVER['REQUEST_URI']."");
exit;
}
// set session
$_SESSION['id'] = mysql_result($query, 0, 'id');
header("Location: /");
exit;
You didn't salt the password.
Also, md5() is considered not strong enough for hashing passwords.
Use hash('sha256', $password) instead.
I assume you're serving this on https, though you don't mention whether you do -- if you're not, username and password travel on the open net in the clear, and that's definitely not very safe.
There's a race condition -- you check whether the username is taken, first, and only later do you insert it. You should use a transaction, a least, and ideally just try to insert (with the uniqueness constraint imposed by the database) and catch the error in case of duplicates. And, you should do this only after all other sanity checks, i.e. when you've convinced yourself that, apart from possible duplicates, the registration attempt is OK.
Little bobby tables will give you a lot of headaches since you do not check for username validity.
You need to salt the password.
This is placed in the wrong place. Move it up a few lines before the $_POST vars are used.
// remove eventuakl space
foreach($_POST as $key => $val) $_POST[$key] = trim($val);
You are escaping the password fields for no reason. They are not being sent to the database. md5($password) is going to the database and it is not escaped.
EDIT: On the login side, you should be trimming anything you are trim on the registrations side.
Your error checking is out of order. I'd do the error checking in this order:
Check for empty fields
Check that the fields have valid values (filtering input)
Escape the fields with mysql_real_escape_string before using the fields in SQL
Check for the user in the SQL table
If you find an error don't continue with further checks. Guard each error check similar to your guard on the final INSERT statement.
You have no edits on the password fields besides using mysql_real_escape_string?
You should do mysql_connect before using mysql_real_escape_string. mysql_real_escape_string will use the connection to determine the character set of the connection. The character set will identify which characters to escape.
You should use parameters instead of building your sql dynamically. It will help prevent sql injection attacks. Little bobby tables will get you.