I probably didn't make my self clear enough (as usual) ;-)

Whilst I advocate hanging session data of the user ID (for systems with a login), other cookies store data to ensure that the user is who they claim to be, that a valid password has been provided and that other parameters, including the client IP address, have not been changed.

To prevent a villain from hand-crafting cookies that will get them a login, the state cookies (which are doubling as security cookies) can be cryptographic hashes of the data plus 'salt' values.

For instance, if my password is 'foobar', setting a cookie of the md5 sum of that value will give me:

3858f62230ac3c915f300c664312c63f

If we know the password, it's easy to recreate that cookie. However, if we hash more than just the value of the password, we can make it MUCH harder to create a valid cookie. Here is a slightly over-the-top example*:

use Digest::MD5 qw( md5_hex ); my $userid='me@example.com'; my $salt1='q398w4hfua9o8has9fp8h'; my $passhash=md5_hex('foobar' . $salt1); my $salt2='q2034rhawpifhasodfha0s0f'; my $ipaddr=$ENV{'REMOTE_ADDRESS'}; my $sechash=md5_hex($userid . $passhash . $salt2 . $ipaddr);

We then set cookies of $userid, $passhash, $sechash. When we go to the next page, we will validate the cookies presented in the HTTP request by recalculating $passhash and $sechash and comparing them with the cookies.

I use a stored procedure to which I feed the values of $userid and $passhash. The procedure returns either true or false depending on whether the re-created hashes match. Note that this method means that neither the password nor a simple hash of the password are ever returned from the database.

After doing this - validating that the password is correct for the user - we compare a calculated value of $sechash against the one in the cookie.

To cut a long story short, if the values of $salt1 and $salt2 are not known (they only exist in the application,) it is highly unlikely that anyone would be able to hand-craft cookies that would allow them to be logged in. We can take this further and use dynamic salt values (possibly generated as per lostjimmy's example) which may be stored in the database against the user ID.

Summary: preserving state in a logged in situation may be achieved safely using the user ID as the key, provided that appropriate security mechanisms - such as salted hashes - are used. In a non-logged in system where security is not an issue, lostjimmy's example is more than adequate.

* - over-the-top in that it uses 2 different salt values.


In reply to Re^3: session management by smiffy
in thread session management by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.