Page 1 of 2

Sessionless Security

Posted: Sun Oct 26, 2008 2:59 pm
by Chalks
I'm building (mostly as a personal project) a small site that allows me to maintain an organized list of things. There are three pages: login, settings, manage list. Normally what I do is have the login page start a session with the username, and pertinent data in it upon validation of the login information. However, I'm toying with simply requiring a password every time you change anything, and using javascript to remember the validated username from the login page. So, in effect, to get past the login page, you need a username and password. To change your settings page, you need just the right password, likewise for the management page. The only security weakness I could think of with this system is that a packet sniffer could pick up plaintext passwords as they're sent to the server using ajax. So, I hash the password client side before it's sent to the server.

Is there anything inherently insecure* with doing things this way? If so, are there steps I can take to make it secure, or is a session really the best option?




*Granted it's not very user friendly (password every time I change something? BAH), but I don't anticipate users changing anything more than once a month or so.

Re: Sessionless Security

Posted: Sun Oct 26, 2008 5:13 pm
by Hannes2k
Hi,
so an attacker can sniff the hash and for further changes the attacker just have to send the hash to the server.

Why do you don't wanna use sessions? Personally I don't wanna enter the password for each change I do, I just wanna enter it on a single site (login page). Which advantages to hope to get if the user have to enter the password for each change?

Re: Sessionless Security

Posted: Sun Oct 26, 2008 5:36 pm
by VladSun
Hannes2k wrote:Hi,
so an attacker can sniff the hash and for further changes the attacker just have to send the hash to the server.
Usually, the client side generates a hash by using a challenge string (as "salt") sent by the server. This challenge string should be different every time the login page is accessed, so one couldn't use hashes previously sniffed.

Re: Sessionless Security

Posted: Mon Oct 27, 2008 7:19 am
by Mordred
1. Packet sniffers are not a realistic enemy here, combating them calls for https, which is a different kind of soup
2. @VladSun, for the challenge-response thing you'll need some server-side storage for the challenge ... like a session or something ;)
3. @Chalks:
using javascript to remember the validated username from the login page
What is "javascript" doing in this sentence? One of us is not getting something - either me->your explanation or you->your implementation ;)

4. If you don't care for replay attacks, HMAC-ed data in the cookies == session

Re: Sessionless Security

Posted: Mon Oct 27, 2008 7:43 am
by VladSun
Mordred wrote:2. @VladSun, for the challenge-response thing you'll need some server-side storage for the challenge ... like a session or something ;)
Yes, you are right - that's for sure. My post is not anwering the OP. :)
I've just wanted to explain how the client-side hash thing should be used to protect against man-in-the-middle attack.

Re: Sessionless Security

Posted: Mon Oct 27, 2008 7:58 am
by VladSun
Hm...
A friend of mine has a USB security gadget. It has to be put once in the security server to synchronized both devices - some kind of random seed value and the time synchronization is performed are stored.
It displays a long key (~12 chars) and it changes it every 1 minute. When he is asked a password he enters (by hand) the current key displayed. The security server checks against his username and the expected password for the current time OR the expected passwords for current time +/- 1minute. If the password is found then the server resynchronize itself if it is needed to.
So ... its $_SESSION free and it is more secure in the meaning of replay attacks, because it minimize the time window to perform the attack. :)
Now let's think how to implement this gadget in PHP and does it worth it ? :)

Re: Sessionless Security

Posted: Mon Oct 27, 2008 7:59 am
by Chalks
Mordred wrote:1. Packet sniffers are not a realistic enemy here, combating them calls for https, which is a different kind of soup
3. @Chalks:
using javascript to remember the validated username from the login page
What is "javascript" doing in this sentence? One of us is not getting something - either me->your explanation or you->your implementation ;)
4. If you don't care for replay attacks, HMAC-ed data in the cookies == session
1.) I was afraid of that. Any tutorials on implementing https with php? I've read a bit about it, but can't seem to find any practical way to use it.

3.) Sorry, I was a little bit confusing. All I meant was if the input password on each page was to have any meaning, the server would also need to know what username to check against. I would just use javascript to keep track of the username. Obviously, a potential attacker could fool the server into thinking it was a different user and then use a dictionary attack for the passwords... but I'll be preventing any changes if a user fails validation more than oh, I dunno, 4 times in a row.

4.) I don't know what replay attacks are, or what "HMAC-ed data" is. >.>

Re: Sessionless Security

Posted: Mon Oct 27, 2008 7:59 am
by Mordred
Btw, if the MITM is able to "write" in the traffic, he still has a good attack: he will "challenge" the client with an empty salt and do an (easier) offline attack on the "clean" hash of the password he gets.

Re: Sessionless Security

Posted: Mon Oct 27, 2008 8:04 am
by VladSun
It will be a bad challenge-response implementation then.
The client side must check if the challenge string is empty. It is required that the server can not send an empty challenge string.

Also, a challenge-response handshake in both directions is a good one to use :)
From http://en.wikipedia.org/wiki/Challenge- ... entication
Simple Example mutual authentication sequence
Server sends a unique challenge value sc to the client
Client generates unique challenge value cc
Client computes cr = hash(cc + sc + secret)
Client sends cr and cc to the server
Server calculates the expected value of cr and ensures the client responded correctly
Server computes sr = hash(sc + cc + secret)
Server sends sr
Client calculates the expected value of sr and ensures the server responded correctly
 
where
sc is the server generated challenge
cc is the client generated challenge
cr is the client response
sr is the server response

Re: Sessionless Security

Posted: Mon Oct 27, 2008 8:13 am
by Mordred
I just checked Maugrim's tutorial: viewtopic.php?f=28&t=38810
In a write-enabled MITM situation, it is even more vulnerable: pass an empty challenge, obtain password hash, use password hash with any other future challenge from the server, profit!

@Chalks: Time to do some reading then. Try Wikipedia for starters.

@VladSun: This is essentially a shared secret (with some additional nice features which are not relevant at the moment). It works well against MITM if you have a secure side-channel in which to share the secret. Asymmetric crypto does that, but that's essentially what https is, so it's easier just to switch to https ;)

Of course the aforementioned "nice features" also play a role (time-based multifactor authorization; you can maybe revoke the key when you lose the device (thus drastically shortening the time the thief has to attack the hardware)

---------------------------------------
Edit: Oops, I misread Maugrim's code a bit (okay, okay, a lot :) ). It doesn't have the issue I describe above, but it does have another one (depending on the hash function; MD5 and SHA-s are affected):
(Note that I haven't tested this (no time now) but I think it should work)
In short, the reponse is calculated like this: response = hash(user + hash(pass) + challenge)

Choose a challenge length so that len(user + hash(pass) + challenge) is a multiple of the hash function block size.

Mallory (the MITM) gives Clide (the client) one such challenge C' and gets R' = hash(user+hash(pass)+C').
Steve (the server) gives Mallory some challenge C'' of which C' is a prefix (C'' = C' + S)
Mallory sets R' as the internal state of the hash function, updates it with S and gets a correct R''.
In order to do this easily, Mallory needs a large enough collection of C'-s so that there is a reasonable probability that the C''-s that come from Steve have a prefix in his C' collection.

Since len(hash(pass)) is constant, the determining factor of how large the collection of C'-s is depends on the length of the username.

This attack should be easily fixable by double hashing (yep, I remember that I wrote that one shouldn't double hash, but I was young and stupid ;) )
R = hash(hash(user+hash(pass)+C))
Now manipulating C doesn't help Mallory, because no suffix attack can be carried against the double hash.

Hmm, I gotta tell Maugrim about this.

Re: Sessionless Security

Posted: Mon Oct 27, 2008 8:35 am
by VladSun
Mordred wrote:I just checked Maugrim's tutorial: viewtopic.php?f=28&t=38810
In a write-enabled MITM situation, it is even more vulnerable: pass an empty challenge, obtain password hash, use password hash with any other future challenge from the server, profit!
I think you should write it also in the Maugrim's thread - some people may not read your post in this thread ;)
Mordred wrote:...but that's essentially what https is, so it's easier just to switch to https ;)
I do agree! :)

Re: Sessionless Security

Posted: Mon Oct 27, 2008 8:43 am
by Mordred
All threads over there are read-only.
I was wrong in the snippet you quote, read the edit of my post. (There's another attack though ;) )

Re: Sessionless Security

Posted: Mon Oct 27, 2008 9:04 am
by Chalks
Wow. This whole topic quite rapidly went past my level of knowledge. That seems to happen any time I ask about security. On the plus side, I learned what replay attacks and HMAC is (sort of... expect another thread in a day or two). Also, I'm a little bit confused by Vlad's challenge response snippet. The idea is clear enough, but how do you have _anything_ client side and still have it a secret? Is the secret generated by the server each time the client side is loaded? In particular:
Client computes cr = hash(cc + sc + secret)
Also also, I've reread your (very) enlightening posts, and though they've helped with several things... I still don't really know if it would be possible to have a _secure_ site without using sessions. Keep in mind this is a very small site, so heavy computational work shouldn't be too big a deal.

Re: Sessionless Security

Posted: Mon Oct 27, 2008 9:13 am
by VladSun
Mordred wrote:Edit: Oops, I misread Maugrim's code a bit (okay, okay, a lot :) ). It doesn't have the issue I describe above ...
It still suffers from the "empty challenge string" issue.

Code: Select all

str = document.login_form.username.value.toLowerCase() + ":" +sha256_digest(document.login_form.userpass.value) + ":" +document.login_form.challenge.value;...document.login_form.response.value = sha256_digest(str); 

->

Code: Select all

str = document.login_form.username.value.toLowerCase() + ":" +sha256_digest(document.login_form.userpass.value) + ":" + "";...document.login_form.response.value = sha256_digest(str);


I.e. the MITM gets the SH256 of "hashedpassword:lowercaseusername:" - still offline "dehashing" attack is possible. There is no time window limit for doing this.
And when the MITM has successfully "dehashed" the "hashedpassword:lowercaseusername:" he can respond with a correct challenge-response string to any server sent challenge string.

Re: Sessionless Security

Posted: Mon Oct 27, 2008 9:18 am
by VladSun
Chalks wrote:Also, I'm a little bit confused by Vlad's challenge response snippet. The idea is clear enough, but how do you have _anything_ client side and still have it a secret? Is the secret generated by the server each time the client side is loaded? In particular:
Client computes cr = hash(cc + sc + secret)
Both challenge strings (server and client side) are regenerated on every page reload. The client side one is generated by using JavaScript - it's not provided by the server.
Chalks wrote:Also also, I've reread your (very) enlightening posts, and though they've helped with several things... I still don't really know if it would be possible to have a _secure_ site without using sessions. Keep in mind this is a very small site, so heavy computational work shouldn't be too big a deal.
Read the Maugrim's tutorial mentioned above. One could always use client's IP instead of $_SESSION['id'] in his code (the possibility that two users behind a single NAT router will authenticate at the same time in a general purpose site is very small IMHO).