• Some users have recently had their accounts hijacked. It seems that the now defunct EVGA forums might have compromised your password there and seems many are using the same PW here. We would suggest you UPDATE YOUR PASSWORD and TURN ON 2FA for your account here to further secure it. None of the compromised accounts had 2FA turned on.
    Once you have enabled 2FA, your account will be updated soon to show a badge, letting other members know that you use 2FA to protect your account. This should be beneficial for everyone that uses FSFT.

PHP Authentication - How to secure password before POST?

defenseman

[H]ard|Gawd
Joined
Nov 20, 2000
Messages
1,738
So I'm creating my own PHP authentication system. Basically the simple process is as follows:

The login page (HTTP...not HTTPS) asks for a username and password. It POSTs the username and password to my PHP authentication scripts. The rest is whatever...

My question is, if I'm using a HTTP connection, how do I secure the password from prying eyes before it hits my server? The only thing I can think of right now is using JavaScript. But since users can turn that off and/or change JavaScript values, is that useful? An attacker could just capture that packet and re-send it at will.

I looked at the code for this site and looked at the POST data. For the password variables (yes there are more than one...), all the data is already hashed/encrypted before getting to the server.
 
Last edited:
Your only option is to use HTTPS. It's either that or the password is interceptable.

*semantic note: Of course, it's ALWAYS interceptable, I use the same meaning as the OP of "interceptable and easily decodable"
 
If you're using a POST over HTTP (not HTTPs), there's no way to make it secure. The best you could do would be to require JS and rely on client-side hashing (say... sequence-num + MD5(password+server-tracked random number).

You might want to look into using HTTP Authentication in your script. You lose the ability to have a pretty login screen.

Another possibility you might want to look into would be the use of OpenID - this way you push the burden of securely authenticating the user onto a 3rd party.

...or you could just suck it up and use HTTPS + POSTs.
 
You could MD5 the password before you send it to your PHP.

What's the point of that? Sure, it might stop anyone who intercepted the request from knowing the password but, if they wanted to compromise the account, they don't need the plaintext password - they can send the captured MD5 across the wire.
 
What's the point of that? Sure, it might stop anyone who intercepted the request from knowing the password but, if they wanted to compromise the account, they don't need the plaintext password - they can send the captured MD5 across the wire.
Not necessarily. There's a way to do this that, while convoluted, would work.

Start with javascript + the password. We're going to do a 1-way hash on the password, but we're going to need some salt that would be difficult for a potential hacker to acquire. Enter in AJAX. Make a request, when doing the hash, for some salt from the server. The server returns some salt ( which it then stores server side for x seconds per IP address per session...or something ), the script hashes the password with the salt and sends it on.

Replay attacks won't work. The attacker would have to know the password to get the right hash.

Is it worth it? Hell no, just go with https. Is it a fun concept to code up and try out? Ya, I'm half way through it :p
 
Not necessarily. There's a way to do this that, while convoluted, would work.

Start with javascript + the password. We're going to do a 1-way hash on the password, but we're going to need some salt that would be difficult for a potential hacker to acquire. Enter in AJAX. Make a request, when doing the hash, for some salt from the server. The server returns some salt ( which it then stores server side for x seconds per IP address per session...or something ), the script hashes the password with the salt and sends it on.

Replay attacks won't work. The attacker would have to know the password to get the right hash.

Is it worth it? Hell no, just go with https. Is it a fun concept to code up and try out? Ya, I'm half way through it :p

Well I started to code it too and by doing so, I ran into what I assess to be the inevitable drawback of having to store clear text user passwords.

If the password the server receives is hashed with any time variable, how does the server check for the right password? The server would need the clear-text password stored in its database and hash it with the stored time variable on the server side. Then and only then can you re-hash the combo and check it against what was sent.

I am right?
 
Well I started to code it too and by doing so, I ran into what I assess to be the inevitable drawback of having to store clear text user passwords.

If the password the server receives is hashed with any time variable, how does the server check for the right password? The server would need the clear-text password stored in its database and hash it with the stored time variable on the server side. Then and only then can you re-hash the combo and check it against what was sent.

I am right?
I'm not sure why it would. Say my password is `password`, so I put that in the form and click submit. The javascript then takes over.

1) md5 hash the password initially; password becomes 5f4dcc3b5aa765d61d8327deb882cf99
2) Then request the salt from the server. Let's pretend the salt that's returned is 7833860101a8d2d624708e5e7d172003. Remember, this hash is stored server side too for later verification
3) I then take the two values and md5 them again, getting 6380bc5f338e2d68e5db2d91d3c216c9 which is sent to the server.
4) The server receives this and stores it. It then pulls out it's hashed password, which is 5f4dcc3b5aa765d61d8327deb882cf99 and looks up the temp salt which was 7833860101a8d2d624708e5e7d172003. It does it's thing with md5 to get 6380bc5f338e2d68e5db2d91d3c216c9 which it then compares to the data it received from the end user finding a perfect match.

Again, is it worth it? Nope, it's solving a problem already solved by https. But if you can't use https, then I guess it's a way to go.
 
I thought the point of authentication schemes like md5 was one-way hash... meaning you can't get the text back after hashing it. ever.

what you've written sounds neat and all, but i don't understand yet how it solves the fundamental problem of ensuring no password recovery? if not https, why not use RSA or AES for the same function?
 
I thought the point of authentication schemes like md5 was one-way hash... meaning you can't get the text back after hashing it. ever.

what you've written sounds neat and all, but i don't understand yet how it solves the fundamental problem of ensuring no password recovery? if not https, why not use RSA or AES for the same function?
I don't really think the method of acquiring our hash matters. But using my method ( which please understand, is more for curiosity's sake than anything else ), how can you recover the password? Further, my method solves two problems; the first is no recovery of plain text password, the second is to prevent replay attacks ( attacker sniffs the wire, finds the md5 hash and replays the session to gain access ).
 
I'm not sure why it would. Say my password is `password`, so I put that in the form and click submit. The javascript then takes over.

1) md5 hash the password initially; password becomes 5f4dcc3b5aa765d61d8327deb882cf99
2) Then request the salt from the server. Let's pretend the salt that's returned is 7833860101a8d2d624708e5e7d172003. Remember, this hash is stored server side too for later verification
3) I then take the two values and md5 them again, getting 6380bc5f338e2d68e5db2d91d3c216c9 which is sent to the server.
4) The server receives this and stores it. It then pulls out it's hashed password, which is 5f4dcc3b5aa765d61d8327deb882cf99 and looks up the temp salt which was 7833860101a8d2d624708e5e7d172003. It does it's thing with md5 to get 6380bc5f338e2d68e5db2d91d3c216c9 which it then compares to the data it received from the end user finding a perfect match.

Again, is it worth it? Nope, it's solving a problem already solved by https. But if you can't use https, then I guess it's a way to go.

Well I'm not going to continue coding up something because I use an additional salt (unknown to anyone except the server) on my server side stored passwords anyway. If your process were to work, I would need to send the user my server side salt in addition to your temporary salt.
 
Well I'm not going to continue coding up something because I use an additional salt (unknown to anyone except the server) on my server side stored passwords anyway. If your process were to work, I would need to send the user my server side salt in addition to your temporary salt.
No, that would defeat the purpose of the salt. The salt sent by the server needs to be random and time sensitive, otherwise you are vulnerable to replay attacks.

Again, this method only protects against two things ( as listed above ), and is completely for curiosity's sake only. https is the proper way to do this.
 
No, that would defeat the purpose of the salt. The salt sent by the server needs to be random and time sensitive, otherwise you are vulnerable to replay attacks.

Again, this method only protects against two things ( as listed above ), and is completely for curiosity's sake only. https is the proper way to do this.

I think you misunderstood. Currently, my passwords on the server are stored by hashing the following: username, clear text password, and a salt (this salt is never sent anywhere...its a secret server salt). This ensures md5 lookups cant be done if and when someone ever see's/steals their password hash by whatever means.

What your introducing is another temporary salt to protect against the issue at hand: securing the password before sending it to the server.

Therefore, I'm saying your technique won't work with my password storage technique.
 
Therefore, I'm saying your technique won't work with my password storage technique.
I don't see why it wouldn't. As long as you can implement the same algorithm server side to acquire your final hash, how you are currently doing it should be adaptable to this method easily enough.

Not that it matters much :) ; this method is just me goofing around. However, I want to make sure any confusion is cleared up.
 
I don't see why it wouldn't. As long as you can implement the same algorithm server side to acquire your final hash, how you are currently doing it should be adaptable to this method easily enough.

Not that it matters much :) ; this method is just me goofing around. However, I want to make sure any confusion is cleared up.

In your step 4, you said: "...It then pulls out it's hashed password, which is 5f4dcc3b5aa765d61d8327deb882cf99...". Your referring to a hash that is the output from md5(clear text password) on both the server side and user side. What I'm saying is that my stored hashes are the output from md5(username, password, server salt). Again, server salt in this case is not the time salt you have been referring to.

So your final sent hash from the user is the output from: md5(password hash, time salt).

On the server side, because the way I store my passwords, my stored hash is never going to compare to the final sent hash the user sent.
 
Ya...not sure I care enough to keep up the back and forth. Suffice it to say my off the cuff algorithm obviously is not going to be a perfect fit for every situation, and would need modification to "fit" specific implementations.

However, the only time we act on a clear text password is client side and that's once.
 
Doing all of this, correctly, yourself is a hassle. That's why OpenID lets you push all the authentication (and lost password recovery and other issues) off onto a 3rd party.
 
On my site I use HTTPS and store the password's MD5 hash in the database. I didn't try to do it my own way though, I just used Spring Security and was done w/ authentication and authorization in a few hours.
 
Further, my method solves two problems; the first is no recovery of plain text password, the second is to prevent replay attacks ( attacker sniffs the wire, finds the md5 hash and replays the session to gain access ).

I'm not seeing how you're solving a replay attack. With a MITM Mallory can intercept the md5(md5($password,$salt)) as it's sent back to the server. All you're doing is making things more convoluted. It's the same thing as a session variable. It can be intercepted and then replayed. While you can limit exposure by setting a validity period for the server side salt, you're still vulnerable for a certain amount of time.
 
I'm not seeing how you're solving a replay attack. With a MITM Mallory can intercept the md5(md5($password,$salt)) as it's sent back to the server. All you're doing is making things more convoluted. It's the same thing as a session variable. It can be intercepted and then replayed. While you can limit exposure by setting a validity period for the server side salt, you're still vulnerable for a certain amount of time.
True, good point. let's say we minimize the attack surface then; the salt is only valid once and for a limited time.
 
True, good point. let's say we minimize the attack surface then; the salt is only valid once and for a limited time.

Better but still vulnerable :)

If you've got an attacker inline who's using a proxy they can simply hijack the valid once salt or the returning session ID and take over the connection. Then again, if you've got an attacker who can figure out whats happening from a packet capture and/or maintain an inline proxy on your connection, you probably have bigger things to worry about.

At the level you've taken it to, I'd say it's all mental masturbation (which is still fun). No attacker would go this in depth. There are other easier targets.

Leave it to us security dorks to over-engineer something which is completely solved by ordering a single SSL cert.

security.png

Courtesy of XKCD
 
Better but still vulnerable :)

If you've got an attacker inline who's using a proxy they can simply hijack the valid once salt or the returning session ID and take over the connection. Then again, if you've got an attacker who can figure out whats happening from a packet capture and/or maintain an inline proxy on your connection, you probably have bigger things to worry about.

At the level you've taken it to, I'd say it's all mental masturbation (which is still fun). No attacker would go this in depth. There are other easier targets.

Leave it to us security dorks to over-engineer something which is completely solved by ordering a single SSL cert.

security.png

Courtesy of XKCD
Lol, exactly. You'll note I've said this a number of times ( use SSL ), too.

I'm working on a prototype just because it sounds like a neat idea. :)
 
Back
Top