Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Is there a way to use an array of hashes as the value of a cookie in CGI.pm?

Replies are listed 'Best First'.
(Ovid) Re: Array of Hashes in Cookies
by Ovid (Cardinal) on Sep 16, 2001 at 01:41 UTC

    As mentioned previously, your idea is a dangerous one. Users can munge the data, it's easy to store the data incorrectly, and there's generally a limit to the amount of data that a cookie can store (I seem to recall that it's 4K, but your mileage may vary). Further, if security is a concern (and it's always a concern), anyone can examine the contents of the cookie and it could potentially reveal information that may give a cracker insight into Bad Things They Can Do.

    All that being said, sometimes we find ourselves in the position of needing to do something that otherwise seems like a bad idea. If you find yourself having no other choice than to store data in a cookie, look into Storable to create the cookie data. Then, you must, must, must use something like Digest::MD5 to create an unforgeable digest to ensure that the data is not tampered with.

    Here's one way to do this:

    use Digest::MD5; my $md5 = new Digest::MD5; my $digest = $md5->md5_base64( $storable_data, $rand ); $storable_data .= $digest;

    In the example above, you compute the digest for the data ($storable_data) that you have created with Storable. You also append a random, difficult to guess string. This string should be read from a file that is not is outside of the Web root. Then, you append the digest onto the data. Since a Base64 digest is always 22 characters in length, when you read the cookie back, use substr to get the last 22 characters and save it as your digest. Take the rest of the data (all the data before the last 22) and compute the digest for it using the same $rand. This digest should match the digest you spliced off. If not, either the data has been tampered with or there is an error in your algorithm.

    The other method would be to compute the digest and send this as a second cookie, but I am loathe to create multiple cookies. However, it's a bit easier to do than appending the digest to the end of the data and it's easier for maintenance programmers to understand.

    Warning: Regardless of what I have said above, you should never send sensitive data in the cookie. Numerous sites send passwords, prices and other things that should not be sent through a cookie. Some sites even issue sequential session IDs! Increase your sessionID by 1 and you might get to hijack someone else's session.

    Cheers,
    Ovid

    Vote for paco!

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Array of Hashes in Cookies
by runrig (Abbot) on Sep 15, 2001 at 22:58 UTC
    You would be better off storing just an ID# in the cookie and storing the actual data locally in a database or in a file with something like Storable.

      Yesh.

      I agree. It's IMHO of course, but I prefer to store datasets like that on the server-side. This is much safer since it prevents the user from altering or poisoning their data. If you're not careful you can accept some poisoned data and bad things could happen. The effects of this will depend on the nature of your app, and what you're doing with that data.

      There is also a size limit with cookies, if you need to keep a large amount of data tied to a user, sometimes you'll hit that wall.

      In addition to Storable, check out Apache::Session.