Forum Moderators: coopster
I am concerned about protecting the security of a users login password. The username and passwords are checked against a database using a simple table of id ¦ username ¦ password. The area of concern is when the the user submits their password.
This is a paid membership system where parts of the site are free but certain articles are restricted to paid members. I want to avoid SSL because I dont want the entire site to be under https because not all content is 'paid content'. I also dont want to place the 'paid content' on https due to the possiblity of users getting that annoying security prompt if they move between secure and non-secure pages. Since the password is essentially paid for its important to protect it, despite the fact that no sensitive information is available by using the password(just paid content).
So basically I am wondering what my options are and what I should be concerned about.
Any help would be appreciated.
Then, like you allude to in your post, I'd protect transmition of the passwords. Using SSL is obviously ideal, but here is a simple way I came up with that can protect the password:
When the user types their username and password in the form, use javascript to "md5" the password when the user hits submit, and then submit the md5 hash. An intruder looking for the transmission of passwords over an unsecured connection would see the "md5" of the password rather than the actual password. Search google for "javascript md5" to get started.
PROS: This protects the password itself.
CONS: The intruder could still use the md5 hash of the password to login as the user. But they at least wouldn't know the user's actual password, since md5 is a one-way deal.
This would mask the password as it's being typed so that someone looking over your shoulder wouldn't see the password.. but it doesn't encrypt it. It's still being sent in plain-text to the server.
Javascript is a good way to go. Though there are few browsers now that don't support Javascript, or a few others that have it disabled, you may want to consider a workaround for those users, since your login script would see a plain-text password and not an encrypted one, it would not authenticate them. You can have your script check to see if the password has been MD5'd, and if not, do it on-the-fly to compare. These particular users would not have the security you want for their passwords, but at least they could still login.
If it's a real concern then use SSL + and store the passwords encrypted (one-way encryption). Period. Do it right. :)
One the other hand if a compromised password wouldn't ruin a life or do any other real harm then you can do w/o SSL and encryption, BUT, in that case *do* have the courtesy to tell the customer that the password they select "can be viewed by system administrators" (or something like that) so they won't use their banking or other "sensitive" password.
<I also dont want to place the 'paid content' on https due to the possiblity of users getting that annoying security prompt if they move between secure and non-secure pages.>
I may be wrong.. but if I recall correctly, the browser only displays this message to the user if they move from secured to unsecured (or vice-versa) through a POST method, for instance, clicking on a submit-type button on a form. But if they move in between secured and unsecured areas with a standard link, then I don't believe the browser displays this message.
That's not really true. If my password is "password", and I use Javascript to run a function on submit that changes "password" to "fjkdgfjls" using a one-way encryption, then "fjkdgfjls" is what will be sent to the server, not "password."
Technically, this is still plain-text since someone snooping will be able to see "fjkdgfjls", but that's not my password, and they cannot go to the site and type in "fjkdgfjls" and login to my account. They can, however, create their own connection to the webserver and send "fjkdgfjls" as the password to login, but they would have to know what I was doing.
And that's pretty easy to workaround too. The encryption Javascription on the login page can be generated to use a random key, and that same key is used on the server-side to authenticate. So while I type "password" this time and "fjkdgfjls" is sent.. next time I could type password and "ruteiouwf" would be sent, so someone snooping and typing in "fjkdgfjls" would not authenticate.
As for SSL, don't forget that you are adding a lot of overhead and it will make the site significantly slower. If you have people's credit cards and social security or other personal info, you owe it to them to protect them. If it's a matter of a small number of people perhaps "stealing" your content, it hardly seems worth it.
See:
A scholarly paper on SSL and performance [citeseer.nj.nec.com] notes that
Our results show that the overheads due to SSL can make web servers slower by a couple of orders of magnitude
See also this paper on the SSL handshake [systemexperts.com]
Everyone's favorite company summarizes nicely [support.microsoft.com]:
If two HTTP web servers are developed with identical HTML, and SSL is applied to only one of the servers, the client browsers will experience a noticeable performance degradation when you browse the SSL web server. Use encryption sparingly. The use of large bitmaps behind an SSL site should be used with discretion.
However, I think the Javascript encryption would not be a bad way to go, and I think it would be pretty darned safe.
- The server generates a random key and implements this key into the Javascript custom encryption code. This key is used on the server side as well, so they must match.
- This function is used on the user's password on submit and sent back to the server.
- The server retrieves a plain-text version of the password (potential security risk, though securing the database would be the best bet, or using reversible encryption on the stored password) from a database and encrypts it using the same function and the same key, but they key that it generated, not the key as determined by the client. This way, someone trying to hack the system cannot use an arbitrary key, they must use the one created by the server.
So being able to see the encrypted password does nothing for getting into the system, because the same plain-text password will encrypt differently each time.
<And letting someone see the crypt of a password in plain text>
How is this different than SSL? Someone can see the encrypted version of everything that goes back and forth. Using SSL doesn't prevent a snooper from seeing the traffic.. it just means that it's encrypted, and that's what they see.
Username and Password are submitted via the SSL page. Then you create a PHP Session.
That session should store the remote IP and maybe an $authenticated=True value or something like that.
Then at the top of every "protected" content page put:
<?require "logincheck.php"?>
and a simple "logincheck.php" could like like:
<?
session_start();
if(!$_SESSION['authenticated'] ) {
Header( 'Location: [mysite.com...] );
exit(0);
}
if( $_SESSION['remote_ip']!= $_SERVER['REMOTE_ADDR'] ) {
Header( 'Location: [mysite.com...] );
exit(0);
}
?>
Then in login.php (which is protected by SSL) it would create the session. Set $_SESSION['authenticated']=True; and $_SESSION['remote_ip']=$_SERVER['REMOTE_ADDR']; if ofcourse the person inputted the correct username/password.
Now when clear packets are sniffed they will only see the PHPSESSID. But even if they tried to hijack the active session it would still be a no go since they would be coming from a different IP and your "logincheck.php" would check for that.
daisho.
Really you can use nothing and you still have a very good level of security. Double checking IP on every call just pushes it to that extra level :)
Reflection - Yes Sir...
daisho.