Re: unique cookie id?
by cees (Curate) on Dec 23, 2003 at 17:51 UTC
|
Since you are using mod_perl, you might as well use apache's mod_unique_id to generate unique IDs for you. From the docs:
This module provides a magic token for each request which is guaranteed to be unique across "all" requests under very specific conditions. The unique identifier is even unique across multiple machines in a properly configured cluster of machines. The environment variable UNIQUE_ID is set to the identifier for each request.
Every request will have $ENV{UNIQUE_ID} set to a unique value.
If for some reason you do not have access to use this module, then you can look at the source code for the implementation that they use to generate a unique ID in an apache environment (remember that in mod_perl2 you may have to deal with a threaded environment).
Update: Just remembered, have a look at Apache::Session::Generate::MD5 for a mechanism similar to yours that Apache::Session uses to generate Session IDs. I would still recommend going with mod_unique_id, but this could be an option for you as well. Please note that you do not need to use Apache::Session in order to use Apache::Session::Generate::MD5...
- Cees
| [reply] [Watch: Dir/Any] |
Re: unique cookie id?
by hardburn (Abbot) on Dec 23, 2003 at 16:32 UTC
|
IIRC, the PID under mod_perl will be the PID of whatever Apache thread you're running under. So the $ToBase62->($$) part will often be the same.
This code makes me nervous, because it gives away the PID of the process. This is a small bit of information to give to an attacker, but I like to know that an attacker has as little information about my system as possible. Further, PIDs are not as random as they appear (unless you know your system does otherwise, such as OpenBSD or a patched version of Linux).
For generating session IDs, I usually use Data::UUID. It's not guarenteed to be truely random (though if you want that it shouldn't be too difficult to patch or subclass), but it is guarenteed unique for a reasonable ammount of time.
---- I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
-- Schemer
: () { :|:& };:
Note: All code is untested, unless otherwise stated
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
Re: unique cookie id?
by duct_tape (Hermit) on Dec 23, 2003 at 18:26 UTC
|
Digest::MD5::md5_hex(Digest::MD5::md5_hex(time(). {}. rand(). $$))
It basically takes an MD5 checksum of a MD5 checksum of a string like this 1072203122HASH(0x80f915c)0.43483996817758877220. It generates a 32 character long string like af68382107551b68473e6a7836ab372e. I would consider that to be pretty unique and unguessable. | [reply] [Watch: Dir/Any] [d/l] |
Re: unique cookie id?
by jdtoronto (Prior) on Dec 23, 2003 at 19:25 UTC
|
The subject comes up here fairly regularly. But you have had some good advice already. Let me add a couple of comments:
- It is never a good idea to use a PID, GID, or machine related value as even a seed for an ID. It can easily result in identical values being generated. In fact I tested this. Using a dual PIII-933 machine with mod-perl and an ID based on pid and time as you are proposing, I got the same ID produced on 31 ocassions out of 2,350,000 requests and on one ocassion got the same ID 4 times in succession. Very very insecure!
- Using Apache::Session or CGI::Session (I prefer the latter - it is much more flexible and works much the same - it is modelled on the former.) using MD5 hashes is good. Even better is using SHA-1 digest pattern which is 160 bits long rather than the 128 bits of the MD-5 digest.
- You should change the cookie-id regularly - if you can. If you tie the value to your session then make sure the session does not persist across browser sessions. If it does, then you should track authentication on top of that.
- I take the MD5 session value from CGI::Session, concatenate the TIME with it and the username then I encrypt the whole lot using Blowfish. That way I can decrypt on the next request and make sure that the time value is the same as that which I have in the session record so that I can be sure that requests are being handled serially. If I get a time skip then I have either lost a request or a response, if this occurs more than once in 64 request/response cycles then either their is something funny going on or the client has an extremely poor connection!
Whatever you choose, good luck!
jdtoronto | [reply] [Watch: Dir/Any] |
Re: unique cookie id?
by cLive ;-) (Prior) on Dec 23, 2003 at 17:49 UTC
|
use Digest::MD5
my $cookie_id = Digest::MD5::md5hex($$.time.$ENV{'REMOTE_ADDR'});
With the hash always being 32 chars long. Works for me.
Though maybe $$ under mod_perl is irrelevant here. Hmmm
cLive ;-) | [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] [d/l] |
|
Unlikely in our instance though :)
cLive ;-)
| [reply] [Watch: Dir/Any] |
Re: unique cookie id?
by adrianh (Chancellor) on Dec 23, 2003 at 22:06 UTC
|
Can I be assured the following code generates a unique cookie id in a mod_perl environment?
Nope.
For example, it's perfectly feasible that two requests could be processed in under a second on a single Apache process, and the same random number come up twice.
Also, since you're not separating the values you use with a delimiter you can get the same string from different values, e.g.:
$ToBase62->(time) |
$ToBase62->($$) |
ToBase62->( rand($$)) |
1234 | 567 | 89 |
12345 | 678 | 9 |
both give the same ID.
Personally I tend to use Data::UUID for creating unique IDs.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Digest::MD5::md5_hex(Digest::MD5::md5_hex(time(). {}. rand(). $$))
| [reply] [Watch: Dir/Any] [d/l] |