again a simple but not very obvious question from me. This time is login in PHP and the session.
AS far as I understand the security side of it:
checking all the variables before sending to MySQL
using $_POST for hiding info
and logging the sessions
Well I have some code 'learned/made' but if you could spot out things that I am missing with a little explanation I would very much appreciate and also could be useful for many beginners like me. (I have read so many questions about it but most of the time the answer started - Despite the fact the code is disastrous in many ways, the specific answer to...)
So here there are:
index.php
<html>
<head>
<title>Website</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<ul><li><a href="index.php">HOME</a></li><li><a href="menu1.php">menu1</a></li><li><a href="logout.php">logout</a></li></ul>
</body>
</html>
session.php:
<?php
session_start();
if (!isset($_SESSION["txtUserId"])) {
require "login.php";
exit;
}
login.php
require_once('db_connect.php');
$errorMessage = '';
if (isset($_POST['txtUserId']) && isset($_POST['txtPassword'])) {
// check if the user id and password combination is correct
$random = '$%hgy5djk3tgbG^bhk';;
$logname=htmlspecialchars($_POST['txtUserId']);
$pass=sha1(($_POST['txtPassword']).$random)
$sql = "SELECT user, pass FROM users WHERE username= :login";
$stmt = $db->prepare($sql);
$stmt->bindvalue( ':login', $logname);
$stmt->execute();
if $stmt['pass']==$pass {
// set the session
$_SESSION['basic_is_logged_in'] = true;
header('Location: main.php');
exit;
}
else {
$errorMessage = 'Sorry, wrong user id / password';
require "login.php";
}
}
?>
<html>
<head>
<title>Login ...</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<?php
if ($errorMessage != '') {
?>
<p align="center"><strong><font color="#990000"><?php echo $errorMessage; ?></font></strong></p>
<?php
}
?>
<form method="post" name="frmLogin" id="frmLogin">
<table width="400" border="1" align="center" cellpadding="2" cellspacing="2">
<tr>
<td width="150">User Id</td>
<td><input name="txtUserId" type="text" id="txtUserId"></td>
</tr>
<tr>
<td width="150">Password</td>
<td><input name="txtPassword" type="password" id="txtPassword"></td>
</tr>
<tr>
<td width="150"> </td>
<td><input type="submit" name="btnLogin" value="Login"></td>
</tr>
</table>
</form>
</body>
</html>
db_connect.php:
<?php
$hostname = "localhost";
$username = "name";
$password = "pass";
try {
$pdo = new PDO("mysql:host=$hostname; dbname=dbnamehere", $username, $password);
//echo "Connected to database"; // check for connection
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
For starters, your code will run an infinite and broken loop if a login error occurs. You require a file from within itself which would not work. I am impressed you took the time however to properly understand some security basics and have implemented PDO into your DB calls and properly escaping your user input with prepare statements.
I am assuming your login page actually exists on index.php. As opposed to 'echoing' statements from your login.php script, I would allow the entire script to process, capturing any errors in a known $_SESSION variable, perhaps:
$_SESSION['login_valid_error'] = "some text".
At the end of the script,
if(isset($_SESSION['login_valid_error']) && !empty($_SESSION['login_valid_error'])) {
header(...) //take the person to logged in page
} else {
header('Location: index.php');
}
then back on index.php, just above your form create an error notice section (with some css) which if page is loaded and the variable exists, echo it:
<?php
if(isset($_SESSION['login_valid_error'])) {
echo '<div class="error">'. $_SESSION['login_valid_error'] .'</div>';
unset($_SESSION['login_valid_error']);
}
?>
making sure to unset the variable once the page is loaded (any new attempts on the page will collect new errors.
I would also consider using something like phpass link is here. It may seem a bit overwhelming at first but download the code and look at the samples. It is actually very easy to integrate and will allow you to skip worry about salting/hashing your user input for things like passwords.
The $_POST variable only hides the data from the user, but it doesn't add any security other than obscurity.
Security considerations should include (at least) a unique token in your form (all forms!) to prevent cross site scripting, validating the token, encrypting the request to the login form (at least), encrypting and salting (unique, unstored salt) your user passwords, as well as validating and sanitizing all user entered-data.
I recommend using a well supported MVC framework, which will handle much of the security for you.
Here are some videos of exactly what you are trying to do, using the CodeIgniter MVC framework:
And the Hello World and Blog examples:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With