Canttouchit Canttouchit - 3 months ago 16
HTML Question

Implementing session to keep user logged, security issue

The following question is a security question.
I'm using Sessions to keep user logged in to my site as long as their browser is open.

Now my php code that keeps user logged is quite simple.
I first create session with user name when user logged inside(authentication.php):

if (($row['user'] == $usr)&&($row['value'] == $pwd)) {
$response = "ok";
session_start();
$_SESSION['name'] = $usr;
break;
}


Then I create from each page a call to JavaScript to check if user exist I change the web page(AJAX)
to look as if user is logged (displaying in header welcome ), the JavaScript looks like this:

function checkUserExistance(data,size)
{
var xmlhttp;

if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var response = xmlhttp.responseText;
document.getElementById("title").value = response;
}
}

xmlhttp.open("POST",url + page,true);

xmlhttp.send();
}


Now on serer side to check if user is logged I use the following simple function, which JavaScript is invoking:

session_start();
if (isset($_SESSION['user'])) {
echo $_SESSION['name'];
}


Now my question is quite simple is that the right way to so it? to keep user authenticated as long as browser open, because if I got that right the JavaScript is on client side meaning that everyone can change it and skip the check with server side post comment on page.

My solution is to add another check when posting comments is to check on server side if user has an open session but then user can pretend to be another user that has already authenticated, this is so frustrating.... what am I missing what should I do?

Answer

Although you probably want to use an established security framework in production, if you are trying to understand the principles of classic security session management, your understanding here is not far off. The important thing is to check the session data at the top of each and every page in your site to make sure the user has NOT skipped the login check.

The cookie sent back from the server used to manage the session will be held in the browser's memory. Before sending any user content from any page, you first check to see if the user is logged on (whether you have a username in the session variable). If empty, the user is not logged on so you send them to a login page asking for their username/password combo;

enter image description here

Bear in mind also, that session state held in memory on the server is not resilient to process recycling nor will it work as expected on a load-balanced web farm.

Subsequent browser requests of any kind, XMLHTTP, HTML, JPGs will all contain this cookie which you can use on the server side to check the session. So what you are doing here will work for instance as the server uses the cookie to tie up your session. As long as your cookies aren't 'guessable' this is largely how username/password authentication systems work.

enter image description here

You don't really need to do anything with XMLHTTP I'd say, unless you want to keep the session open for longer. Typically, the server will expire cookies after a few minutes (configurable).

So for a poor-man's security system, in summary;

  1. Every browser request, check $_SESSION['user'], if it's empty direct to a login page.
  2. On Login page, check username/password matches (an exercise for the reader:)) if so, store user's name in session (which will automatically return cookie)

That's basically it. The browser cookie will be sent each time and as long as you don't forget to check every time you get a request you're good to go. This, and many other reasons is why it's good to use a framework, but I think it's useful here to understand the basics as you're doing.

Other things to remember;

Firstly, you should ONLY check the security on the server side. You can't do this in client javascript. Secondly, you need to do this for each and EVERY request. The browser will send a cookie every time so as long as that matches a session variable you checked the userame/password of earlier you're good. If there is NO cookie, or the session variable that cookie relates to does NOT contain a user variable you set earlier then the user is not logged in and you should redirect them to the logon page again. You do this for every request.

Remember that your AJAX call is still a request, so that too must go through the same logon check on the server side. The easiest thing to do would be to set the page title in PHP rather than in client javascript, but if you want to make it an ajax client then you need to handle the possibility that the server may reject your request due to the reasons stated above and redirecting you to a login page won't be the response you'll expect from XMLHTTTPRequest. So at the very least you'll need more sophisticated error handling, at best you could rewrite your logon process as AJAX-only.

Here's some pseudo code for the server;

if session(name) is empty then
    if IsAjaxRequest then
        send ajax access denied response code and exit
    else
        redirect browser to login page
    endif
else
    if IsAjaxRequest then
         send ajax data // eg. title
    else
         send html page (injecting session(name) into title)
    endif
endif

That said. I wouldn't write that pseudo code. I would use different endpoints (pages) to serve up browser HTML responses and AJAX API responses instead, but hopefully you'll get the general idea of what your choices are.