1

Please help me to validate one session only at a time, kindly see the below script which currently allows the same username to login any number of sessions.

I am not sure when and where to validate the session, help me in adding only those few lines which can validate the session for a username.

<?php // accesscontrol.php
include_once 'common.php';
include_once 'db.php';

session_start();

$uid = isset($_POST['uid']) ? $_POST['uid'] : $_SESSION['uid'];
$pwd = isset($_POST['pwd']) ? $_POST['pwd'] : $_SESSION['pwd'];

if(!isset($uid)) {
  ?>
  <!DOCTYPE html PUBLIC "-//W3C/DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
<title>Login</title>
<meta http-equiv="Content-Type"
  content="text/html; charset=iso-8859-1" />
<head>
<style type="text/css">
<!--
.style1 {
    font-size: 16px;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
.style3 {
    font-size: 12px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}

body {
background-color: #D7F0FF;
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
}

-->
</style>

  </head>
<body>
  <h1 class="style1"> <br><br>Amogh Site - Login Required </h1>
  <span class="style3"><br>
  You <strong>must login to access this area </strong>of the site. <br>
  <br>
  If you are not a registered user, please contact your Admin
     to sign up for instant access!</span>
  <p><form method="post" action="<?=$_SERVER['PHP_SELF']?>">

<span class="style3">User ID:&nbsp;&nbsp;&nbsp;&nbsp;    
<input type="text" name="uid" size="12" />
<br>
<br />
Password:</span>    
<input type="password" name="pwd" SIZE="12" />
<br>
<br />
<input type="submit" value="Login" />
  </form></p>

</body>
  </html>
  <?php
  exit;
}

$_SESSION['uid'] = $uid;
$_SESSION['pwd'] = $pwd;

dbConnect("hitek_svga3");
$sql = "SELECT * FROM user WHERE
    userid = '$uid' AND password = '$pwd'";
$result = mysql_query($sql);
if (!$result) {
error('A database error occurred while checking your '.
    'login details.\\nIf this error persists, please '.
    'contact you@example.com.');
}

if (mysql_num_rows($result) == 0) {
  unset($_SESSION['uid']);
  unset($_SESSION['pwd']);
  ?>

  <!DOCTYPE html PUBLIC "-//W3C/DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title> Access Denied </title>
    <meta http-equiv="Content-Type"
      content="text/html; charset=iso-8859-1" />
    <style type="text/css">
<!--
.style1 {
    font-size: 16px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}
.style3 {
font-size: 12px;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
-->
</style>  

  </head>
  <body>
  <br/>
  <br/>

  <h1 class="style1"> Access Denied </h1>
  <p class="style3">Your user ID or password is incorrect, or you are not a
 registered user on this site. To try logging in again, click
 <a href="<?=$_SERVER['PHP_SELF']?>">here</a>. To access, please contact our Admin     !</a>.</p>
  </body>
  </html>
  <?php
  exit;
}

$username = mysql_result($result,0,'fullname');
$_SESSION['user'] = mysql_result($result,0,'userid');
$_SESSION['email'] = mysql_result($result,0,'email');
$_SESSION['notes'] = mysql_result($result,0,'notes');

?>
user1114409
  • 565
  • 3
  • 13
  • 26
  • Your script seems to be vulnerable to [SQL injections](https://www.owasp.org/index.php/SQL_Injection). Have a look at [Best way to prevent SQL injection?](http://stackoverflow.com/q/60174/53114) – Gumbo Dec 02 '12 at 11:11
  • Because HTTP is stateless, it's *difficult* to determine whether a user's session has expired and thus whether a fresh login attempt is a new session or a duplicate of an existing one. – eggyal Dec 02 '12 at 11:11
  • @eggyal it is possible then to simply delete any previous sessions and create a new one each time. – ose Dec 02 '12 at 11:12
  • @ose: True. Perhaps I had misunderstood the question, as my reading was that the intention was to deny further login attempts rather than kick out existing sessions. – eggyal Dec 02 '12 at 11:13
  • 2
    BTW just as a general piece of advice, it is wise to remove identifiable information such as the company name when you post code. You never know who might later on discover this code, surmise that you are vulnerable to a particular style of SQL injection attack and break into your system... – ose Dec 02 '12 at 11:13
  • @eggyal Fair enough, in that case it would be possible to maintain a timeout associated with each session, so that if duplicates were made during the timeout period they would be denied, otherwise the old session is deleted. – ose Dec 02 '12 at 11:14

2 Answers2

0

Firstly, why are you storing passwords in session variables?

Secondly, your code assumes that the session variables 'uid' and 'pwd' will exist if the POST vars 'uid' and 'pwd' don't, so you'll need to make sure that either or exist before you allow your script to continue. This will have to be done AFTER the session_start() function:

<?php // accesscontrol.php
include_once 'common.php';
include_once 'db.php';

session_start();

if(
      (!isset($_SESSION['uid']) || !isset($_SESSION['pwd'])) &&
      (!isset($_POST['uid']) || !isset($_POST['pwd']))
{
     //Redirect or throw exception or whatever
}

$uid = isset($_POST['uid']) ? $_POST['uid'] : $_SESSION['uid'];
$pwd = isset($_POST['pwd']) ? $_POST['pwd'] : $_SESSION['pwd'];
Wayne Whitty
  • 19,513
  • 7
  • 44
  • 66
  • where should I redirect after checking the condition, am not very clear, pl help – user1114409 Dec 02 '12 at 11:30
  • I have added this in the script, but it still allows more than user to login with the same userid. One more point to note is, this script is run only in local server and NOT over the internet, hence there is no issue of mysql injection or any such issue. – user1114409 Dec 02 '12 at 11:54
0

You should not:

  • Keep cleartext password in the database
  • Using mysql extension
  • Develop in 2012 without a framework

The point of the question is: how does PHP tell which user a request comes from? Last time I checked it used a token sent as a GET parameter or with a cookie in the HTTP request header section (I think it was called PHPSESSID).

Obviously to guarantee that nobody steals sessions, identity token must be exchanged over a secure channel, ie once the user logs in you have to generate a session id and disable plain HTTP sockets on port 80. The scripts that need a logged user must be kept in a separate host which only allows HTTPS on port 443.

The session ID will be assigned from the login script and will be kept in a column in the user table. BTW, regular applications use a separate table to associate sessions to user, but since you require one client per user a column in the user table is enough.

So when a request comes with a session token, your authorization logic will check in the user table if the token is still valid. It should use the token to authenticate the user, so if the request doesn't contain one or the token is not found in the database, you issue a 403 FORBIDDEN and suggest the login URL in the Location header - you can also write a HTML page with an <a> link in the case the agent doesn't automatically follows the redirect.

The login script is committed to update the column with the token, depending on what you want to do: invalidate the old session or prevent the creation of new ones until the user explicitely logs out on the other client (the latter causes troubles in the case the user can't access the old machine where he previously logged in from, maybe because if powered off the mobile device or because it was in a different building)

Raffaele
  • 20,627
  • 6
  • 47
  • 86
  • Is there any link where this example is demonstrated, pl share. – user1114409 Dec 02 '12 at 11:31
  • @user1114409 I don't have any link, it's not an original idea, it's just how it works. In the security area there's usually the one-solution-per-problem approach. Just download Wordpress (or Drupal or Joomla, or Cake or Zend) and look at the authentication and authorization routines. – Raffaele Dec 02 '12 at 11:41
  • @user1114409 look at [`CakeSession`](https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/CakeSession.php) and [`DatabaseSession`](https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/Session/DatabaseSession.php) – Raffaele Dec 02 '12 at 11:48
  • Old answer, but I disagree on the quote "You should not" "Develop in 2012 without a framework". I mean, what about the learning process? Do you start a ride without knowing the vehicle you are riding? That being said, good afternoon :-) – Jonathan Oct 03 '17 at 15:52
  • You'll learn way more from the worst framework than from yourself – Raffaele Oct 03 '17 at 16:22