I'm looking for a secure way to let users login on my website. Currently, I've always used a session system, like this:


if (validPass() || isset($_SESSION['userId'])) {
    if (isset($_GET['logout'])) {
    } else {
        if (!isset($_SESSION['userId'])) {
            $_SESSION['userId'] = $the_id;
        // User is logged in
} else {
    // Show a login form

Is this the secure way, or are there better systems? What should I look out for?

  • I hope this question includes enough information and isn't too broad. If otherwise, please ask more info / specification! – Keelan Apr 12 '13 at 15:11

A more secure way? Use https along with this. There are two vulnerabilities here:

  • When the user logs in, the password that is sent over can be easily read by anyone snooping on your connection. This can't happen on an https connection.
  • If a user is already logged in, someone snooping on your connection can just copy over the session cookies. In HTTPS, cookies are transmitted securely, so there isn't much of an issue.

You may also want to log the user IP address and not let them switch, though this may get annoying (for a user like me who is behind a university proxy with rotating external IPs, I'll never be able to log in).

A final observation: Don't use GET for the log out bit.. Try not to use GET for anything which triggers a change -- it's fine for navigation, but not for anything which will lead to something changing on the server (a logout, or anything that writes to a database). See the prescribed usage of GET and POST for more details.

If you implement the above, then also make sure that the referrer of a POST request is your site and not some other site. (This, along with the above, will help prevent CSRF attacks).

To prevent clickjacking, disable framing via javascript and the X-Frame-Options: deny header.

  • 1
    Regarding "use POST" - this will not protect against CSRF attacks, at all. Malicious sites can just as easily send POST requests (hidden forms and iframes). – Joel L Apr 12 '13 at 16:40
  • @JoelL: That's not csrf, that's clickjacking. And it can be prevented by disallowing framing. – Manishearth Apr 12 '13 at 16:44
  • I'm sorry, but that's not really accurate. Clickjacking would imply embedding the site in frame, and tricking the user to make actions in that frame. A hidden POST request doesn't require any user interaction. – Joel L Apr 12 '13 at 16:48
  • @JoelL: Hmm, you're right. For some reason I assumed that POST from another website would not use the session cookies. I'll edit then. – Manishearth Apr 12 '13 at 16:56
  • Cool. You should also add "…and the X-Frame-Options: deny header" to your last sentence. The header is now supported by all/most modern browsers, so JS shouldn't even be needed for that, soon. – Joel L Apr 12 '13 at 17:02

Just to enhance the check method try to add some things about user secure login.
Try to use force cast with (int) in order to avoid any case that the attacker could be use to pass any malicious string and a not empty check also.

if (isset($_SESSION['userId']) && (!empty($_SESSION['userId'])) {
  $user_id= (int)$_SESSION['userId'];
} else {

echo 'Test: '.$user_id;

To add to answer by Manishearth , I would also recommend the following :

  1. Set cookies to be HttpOnly and Secure Always write secure ( To make sure that its only readable by HTTPS enabled site) and HttpOnly (To make sure that its not accessible through Script : Can be dangerous if XSS comes up on your site)

  2. Enable front end headers like Content Security Policy, Strict-Transport-Policy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.