Adrian Noland wrote:

In regards to slides 29 and 30, can you elaborate and give a more detailed
example what they are trying to say?  Are they saying that the session key
should contain a hash of the data? Or does the hash become the "salt" in
crypting the data? Finally, how does doing that make it easier to prevent
circumvention and forgeability.
Let's take it a step at a time... Imagine we've got a token of the following format...

$token="$user_id:$session_id"

The session_id doesn't have to be unpredictable -- it could could from an auto_increment column in a database table... With the caveat that people could estimate the usage of your site by looking at the session id's.

You could put this in a cookie, and it would work quite well, as long as you didn't have users who knew how to look at or change the cookies. An attacker who understands cookies can easily change the user id, or session_id.

   To protect the cookies from tampering,  we could do something like

$hash=sha1($token);
$signed_token="$hash:$token";

We could check the integrity of the token by recomputing the hash and see if it matches the one in the signed token. This protects against accidental damage, or very simple attacks. Still, it's quite possible that an attacker could guess what you're doing: it wouldn't be safe at all in an open source system.

That's where the salt comes in... For a particular web site, we create a random "salt" that, effectively, gives us a unique hash function for our web site.

$salt="... a random salt defined in a per-site configuration file ...";
function private_hash($token) {
   global $salt;
   return sha1("$salt:$token");
}
$private_hash=sha1("$salt:$token");
$signed_token="$private_hash:$token";

   Now,  nobody can alter your tokens unless they know your salt.

Because the tokens are cryptographically signed, the token itself is a proof that somebody has logged in -- you don't need to look at the database or keep ~any~ server side state. This makes it a highly scalable system... This basic approach is used on some of the biggest sites in the world, such as yahoo.com.

   Except for one little detail:  replay attacks.

Nothing stops a person from saving his token and presenting later -- after his account may have been deactivated, or after associated session information has been purged (an error condition.) An attacker that gets the person's cookie jar, or who intercepts network traffic, can also steal the token.

It's not possible to completely protect against sophisticated attacks where a hostile party controls your network without installing complex software on both ends, and solving some intrinsically difficult problems having to do with mutual authentication. Let's just say that the developers of SSL have solved these problems, and that you should use SSL for applications with the strongest security needs.

We can, however, make replay attacks a lot harder by adding a timestamp... Now the token looks like

$timestamp:$user_id:$session_id

   Now we're keeping a table on the server that looks like

create table session (
   session id      ... session id ... primary key
   user_id          ... user id ...,
   last_updated  ... timestamp ...,
   begin_time    ... timestamp ...,
   end_time       ... timestamp ...
);

   Now we've got two constants:

REFRESH_TIME: how old a timestamp is before we issue a token with a new timestamp and write the timestamp to the last_updated column.
EXPIRE_TIME: how old a timestamp is before we eliminate the session.

You might think you could put the client ip address in the token, and lock the session to an ip address to make it harder to steal tokens. I tried this, but found out that some of the largest ISPs (such as aol) have a proxy server that makes users seem to "jump around". You can do it if you know people are logging from a sane ISP, but you can't do it in general.

   ---

This system can be improved in numerous ways, such as adding anonymous sessions, operating in a split http/https mode, and caching authorization system in the token.

If you're worried about information leakage (you don't want someone to know that he got session 88427 yesterday and 99105 today), you can encrypt the token. But be careful... It's easy to use cryptography the wrong way: don't rely on encryption to protect token integrity against tampering -- most of the obvious schemes don't really work.


_______________________________________________
New York PHP Community Talk Mailing List
http://lists.nyphp.org/mailman/listinfo/talk

NYPHPCon 2006 Presentations Online
http://www.nyphpcon.com

Show Your Participation in New York PHP
http://www.nyphp.org/show_participation.php

Reply via email to