Member Avatar for iamthwee

Guys,

I got a quick question, I want to know what you guys use or what resources you have for a complete secure PHP login system. Using salts, hashes and sessions. No fancy Jquery stuff, just stripped down.

Some limitations:

-No use of PDO, the server I'm using has a lot of legacy crap which requires the old version of PHP.
-No fancy Jquery/Javascript (I just need the bare bones PHP and HTML)
-No fancy MVC stuff.

At the moment the best one I could find is

https://github.com/panique/php-login-minimal

Any tips or ideas would be best appreciated.

Looks like a decent start at first glance.

Member Avatar for iamthwee

Prit you on community chat?

Would it not just be as effective to write your own?

Member Avatar for iamthwee

Nope, needs to be for commerical project (hopefully), in theory I could spend time researching this but the rest of the system is way too complicated... So my time best be spent there mate.

Member Avatar for diafol

Will the rest of the system need to integrate with your login class? Just the session id maybe? That bundle seems to use a db config too. You'll be looking to just have the one for the whole site?

My general method is something like this:

step 1: Open session and see if a user is active.
step 2: Perform your routing functions and see if the user has access to the page requested.
step 3: Allow access, or show a "not allowed" message, or even simply show a blank white page with no information at all, or redirect them, if not allowed.
step 4: If no user is in session already, then either show the "public" information, OR send them instantly to the login and register page.
step 5: process the login, test if user exists, etc etc.
step 6: Return fail if bad login. Here you could track IP addres, log how many login attempts were tried, perform login timeouts etc.
step 7: If user matches, put the necessary user data into session and redirect them to the start page of your app, they are now logged in.
step 8: If they click a logout action, get rid of all that session/cache/cookie info to make sure they are logged out, and then redirect to public page or back to login screen. Search online for best way to destroy session.

For the incidentals... You need to be very careful how you return failed login attempts, never show things like sql errors being returned. Don't hint whether they typed a username right but pass wrong, or vice versa. Don't have one error that says "no such user" and another that says "wrong password" because that tells a hacker they found a valid user. Don't show sql errors because they can learn a lot from posting bad data. Simply show "login failed", all other errors logged only and suppressed from view.

You can store usernames as plain text, that's pretty normal. Store the password is up to you but is highly debated. In the old days I would SHA1 on an MD5 of a salt + pass. But these days, all the salting, random number generating, hashing, DES encryption etc can all be dealt with the native PHP crypt() function. As simple as $passwordhash = crypt("mypassword").
Crypt() is a one-way hash, so there is no "decrypt" method. This means you can never tell a user what their password is, all you can do is compare the hashes. When testing the password, it's as simple as:

if (crypt($user_input, $hashed_password) == $hashed_password) {
   echo "Password verified!";
}

Essentially you pass the original hash back to crypt AS the hash itself when testing. Ya that sounds weird, but it works. So you would first see if any such user exits, and if it does, read the password that is stored, then run the function above, passing that password as the hash. Lookup the crypt() function for its many options.

This all sounds complex, and naturally a good secure login system and protected website IS quite complex by nature, there are lots of security concerns. But as far as the hashing, read up on the crypt() function because it's built in to the PHP core and supports many algorithms as well as using your own hash should you want to generate one yourself. Some people generate their own salts using a two part system where they have a keyword stored within the programming, and this keyword is matched with a generated or standard salt that is set elsewhere, perhaps by the person who installs and uses your app. So like $salt = MD5("programmed text" . $generatedtext). Something like that. Some generate salts by using a timestamp + random string.
The other concern about salts is, you can use ONE salt you come up with for every password you hash, OR you can generate a unique salt for every password you store, but you'll have to also store that salt so you can test the password later. Using a unique salt for every password means rainbow tables are pretty much moot, and no pass has the same salt, this makes things very difficult to hack. Even the fact that if two users create the same password, it wont' be the same hash in the DB. But using one salt for everything is not horrible, it's quite common and acceptable I would think.

As for using the session, just make sure your app is testing the session that the user is allowed to be there or view it, and redirect or die() or whatever you need if there is no session. Often in my session I'll just have a $user array and in there everything I need. So I could do like:

if (!$_SESSION['user']['group']=="admin") {
   echo "Go away!";
} else {
   echo "Welcome Secret Agent Smith!";
}

It is much easier to password protect an entire page, than to try and do little parts of a page as protected here and there in the content.

I just came up with all this off the top of my head, sorry it's not very organized, but hopefully gets you thinking. Programmers will argue endlessly about the best way to secure data in a database and how to hash passwords, but really it comes down to avoiding brute force techniques, mysql injection hacks, proper database permissions, no exposing php and errors and such, slowing down the hash test, implementing timeouts for failed attempts, logging IPs and looking for patterns, etc etc.
It also depends on how sensitive the stored data is, you want to protect your users, and how popular the website is (do any hackers really turn their attention to small fry?) Try to avoid the simple script kiddies and the easy hacks and MySQL injection techniques.

Anyway, good luck!

commented: nice +14

you need simple mysql and apachi server for php..

This a great thread. Many concerns addressed and answered.

I am working on the same sort of login system.

I saw that this thread was still open so I thought I would enter in my opinions on this topic.
Tip 1:
When designing an authentication system you will want to keep all passwords and their associated hashes out of shared memory and away from public access. So for instance, lets say you were doing an object oriented design, the hashes may not be assigned to a global variable as that is what is called shared memory. Just a side know, recently there have been a few exploits with accessing shared memory so assume all shared memory is public.

Tip 2:
Hash a portion of the hashes as the salt and a hash of the hash as the string to be hashed
eg $hash=substr(sha2(sha1($password),0,8).substr(sha1(sha1($password)),18));
This will ensure that nobody can reverse the hash using a brute force database even with technology that exists in the next century which may be something like 256GHz 65,000 core and still they won't be able to crack your passwords because you used a custom hashing algorithm. On the other hand if you just do sha2('salt'.$pass) then in the next 10 years when quantum computers are due a simple loop though the first 2^256 combinations will result in finding your password and even with a sault a fast internet connection can do it on the live with the new network technology due in 10 years faster than fibreoptic by 1000 or so times the speed but is currently still under development.

Tip 3:
Remember sessions are hackable as they can have data injected or traced from them by a malicious user. So if for instance you did $_SESSION['login']=false; then a user could simply set that to true with an injection method and they will be signed in. What makes this worse is you could have $_SESSION['admin']=false; and if they set that to true then they can delete your website. So always store these things in databases or flat file and instead of using sessions, send one cookie to the user containing a hash as a reference id. If you really desire you can add that reference id in $_GET too and that reference id would be used to check the database for the user inter page variables for the user processing the page.

Curious...
I know a CMS is not the answer to every project, but I'm curious what your reasons are for re-re-rebuilding a login system and user managament when there are so many systems to choose from out there?

I've been on Daniweb for about 6 yrs and it seems that a lot of coding-by-hand goes on here. That's fine. It's a successful way that many projects get launched.
In this specific case, I would like to know what consideration you gave to a CMS and if there were any requirements that prevented you from considering a CMS.

I do a lot of public speaking about OpenSource and the Web. I'd like to take a little of what you have to say and use it in my portrayel of the non-CMS users.

Thanks!

Doug Vann

Member Avatar for iamthwee

Hi Dough, that your for you question.

The site I've been asked to build is very specific so a CMS already out there simply isn't an option. Plus it would take so much longer to reverse engineer.

This is why I was just looking for a simple and robust login script. The one I found was good, but even that needed stripping down to its bare essentials.

Hope that helped.

Member Avatar for diafol

I agree, many bespoke sites just don't lend themselves to the CMS. There are many pros and cons for devising your own solutions just as there are for using a CMS. Security and vulnerabilities are major issues of course. I would imagine that the prevelance of DIY scripts on DW php forum is due mainly to the 'I want to learn how to do it', rather than a 'I don't want to use a CMS'. After all, any developer worth his or her salt should be able to write their own, or at least understand how a CMS implements a particular functionality. After all, using a CMS, you're investing a considerable amount of trust - especially if you use a relatively little-used add-on from an obscure third party developer. Same goes for a simple third party script or class of course.

At least the majority of popular php scipts and CMS are open source and well documented, so you could at least investigate how they work - unlike browser add-ons which may be free to use, but you have no idea if they're safe or not!

Get on a new server, with PHP5.X.
Using outdated versions is not recommended.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.