length of a session ID ...
Moderator: General Moderators
- pavanpuligandla
- Forum Contributor
- Posts: 130
- Joined: Thu Feb 07, 2008 8:25 am
- Location: Hyderabad, India
length of a session ID ...
Hii..
can anyone provide information about the length of PHPSESSID?
i saw JSESSID is of 16 characters length and in my application PHPSESSID is of 26 characters,
but in gmail, i saw SID of above 100 characters..
does this session ID length has any prominence?
please post detailed session ID information like,
how many characters can a PHPSESSID contain?
are there any security vulnerabilities if sessid is small?
Many Thanks,
Pavan.P
can anyone provide information about the length of PHPSESSID?
i saw JSESSID is of 16 characters length and in my application PHPSESSID is of 26 characters,
but in gmail, i saw SID of above 100 characters..
does this session ID length has any prominence?
please post detailed session ID information like,
how many characters can a PHPSESSID contain?
are there any security vulnerabilities if sessid is small?
Many Thanks,
Pavan.P
Re: length of a session ID ...
As long as it is unique it doesn't matter. I'd say the longer sid the bigger chance of it being unique. Well of course should be somehow hard to guess 
Re: length of a session ID ...
The purpose of SIDs is to be - as jmut already said - unique and unguessable. This is generally achieved by taking a sufficiently strong random string, the length does not matter, as long as it doesn't truncate the entropy of the random. An example:
Here is a 32 character random hexadecimal string:
Here is a 8 character random hexadecimal string:
Which one is better (i.e. harder to guess)? The longer or the "more random" one? Let's see:
Assuming that mt_rand() is a perfect random (which it isn't but that's another matter), the first SID has an entropy of 7 bits (128 = 2^7), while the second one has 32 bits (16^8 = 2^32). In other words, one would expect to guess the first SID in 64 attempts on average (or a bit more than 8 attempts if we don't care whose SID we're stealing), while for the second case it's 2^31 attempts for a certain SID and 2^16 attemps for a random SID.
Note that these are artificial examples so we can compare their entropy. None of them is suitable for practical usage!
Here's one for homework: How strong is this random SID (again assuming that rand and md5 do not lose entropy):
The best way to deal with SIDs in PHP is not to deal with them at all - the internal method for generating them will be better than anything one can cook at home. It uses strong random values (with enough entropy) and long enough SID strings.
I see no point in having SIDs as long as 100 characters. My guess would be that gmail stores some actual information (apart from the random component) in there.
Edit: added some bolding to a paragraph above.
Here is a 32 character random hexadecimal string:
Code: Select all
$s = md5(mt_rand(128)); //32 charactersCode: Select all
$s = '';
$sChars = '0123456789ABCDEF';
for ($i=0;$i<8; ++$i) $s[$i] = $sChars[ mt_rand(16) ]; //8 charactersAssuming that mt_rand() is a perfect random (which it isn't but that's another matter), the first SID has an entropy of 7 bits (128 = 2^7), while the second one has 32 bits (16^8 = 2^32). In other words, one would expect to guess the first SID in 64 attempts on average (or a bit more than 8 attempts if we don't care whose SID we're stealing), while for the second case it's 2^31 attempts for a certain SID and 2^16 attemps for a random SID.
Note that these are artificial examples so we can compare their entropy. None of them is suitable for practical usage!
Here's one for homework: How strong is this random SID (again assuming that rand and md5 do not lose entropy):
Code: Select all
$s = '';
$sChars = '0123456789ABCDEF';
for ($i=0;$i<1024; ++$i) $s[$i] = $sChars[ mt_rand(16) ];
$s =md5($s);
The best way to deal with SIDs in PHP is not to deal with them at all - the internal method for generating them will be better than anything one can cook at home. It uses strong random values (with enough entropy) and long enough SID strings.
I see no point in having SIDs as long as 100 characters. My guess would be that gmail stores some actual information (apart from the random component) in there.
Edit: added some bolding to a paragraph above.
Last edited by Mordred on Mon Sep 29, 2008 9:18 am, edited 1 time in total.
- pavanpuligandla
- Forum Contributor
- Posts: 130
- Joined: Thu Feb 07, 2008 8:25 am
- Location: Hyderabad, India
Re: length of a session ID ...
Thanks alot mordred.. i'm using mt_rand() function now to generate random session id's.
i understood the concept..
Many Thanks,
Pavan.P.
i understood the concept..
Many Thanks,
Pavan.P.
Re: length of a session ID ...
pavanpuligandla wrote:Thanks alot mordred.. i'm using mt_rand() function now to generate random session id's.
i understood the concept..
Mordred wrote:The best way to deal with SIDs in PHP is not to deal with them at all - the internal method for generating them will be better than anything one can cook at home. It uses strong random values (with enough entropy) and long enough SID strings.
Re: length of a session ID ...
Sorry to resurrect an old thread, but I think it's good to be knowledgeable of how PHP's session IDs really work, and why they look the way they do.
As has already been stated, session IDs must be unique and unguessable.
I'm not sure how much entropy PHP uses for session IDs by default, but on Linux you can increase the entropy with these php.ini settings:
Note that session.entropy_length is in bytes, and you can set it higher if you want. Another thread discusses sufficiently-random numbers.
The original question was regarding the length of session IDs generated by PHP. The length is affected by the php.ini settings session.hash_function and session.hash_bits_per_character. For session.hash_function, 0 means MD5 (128 bits) and 1 means SHA-1 (160 bits). (Note that PHP 6 opens session.hash_function up to many more hash algorithms.)
The session.hash_bits_per_character setting lets you pick the notation that is used for displaying these 128 or 160-bit hash digests. It can be between 4 and 6; 4 means hexadecimal (2^4 = 16), 5 means base-32 (2^5 = 32) and 6 means base-64 (2^6 = 64). (Note that these base-32 and base-64 notations are not exactly the same as the standardized Base32 and Base64 encoding schemes.)
If you specify SHA-1 and 5 bits per character, your session IDs will be 32 characters long because 160 / 5 = 32.
In some cases there are fewer bits left at the end than bits per character, so the last character of the session ID will have a smaller base than the others characters. For example, using MD5 with 5 bits per character yields a 26 character session ID. The first 25 characters can be any one of the base-32 characters, but the final character will be in the range 0-7. This is because 128 / 5 = 25.6. 128 % 5 leaves only 3 bits for the final session ID character, and 2^3 = 8.
The same thing happens when using MD5 with 6 bits per character (the last session ID character will be in the range 0-3) or SHA-1 with 6 bits per character (the last session ID character will be in the hexadecimal range 0-F).
As has already been stated, session IDs must be unique and unguessable.
I agree with Mordred, don't try to contrive your own method for generating session IDs.Mordred wrote:The best way to deal with SIDs in PHP is not to deal with them at all - the internal method for generating them will be better than anything one can cook at home. It uses strong random values (with enough entropy) and long enough SID strings.
I'm not sure how much entropy PHP uses for session IDs by default, but on Linux you can increase the entropy with these php.ini settings:
Code: Select all
session.entropy_file = /dev/urandom
session.entropy_length = 128The original question was regarding the length of session IDs generated by PHP. The length is affected by the php.ini settings session.hash_function and session.hash_bits_per_character. For session.hash_function, 0 means MD5 (128 bits) and 1 means SHA-1 (160 bits). (Note that PHP 6 opens session.hash_function up to many more hash algorithms.)
The session.hash_bits_per_character setting lets you pick the notation that is used for displaying these 128 or 160-bit hash digests. It can be between 4 and 6; 4 means hexadecimal (2^4 = 16), 5 means base-32 (2^5 = 32) and 6 means base-64 (2^6 = 64). (Note that these base-32 and base-64 notations are not exactly the same as the standardized Base32 and Base64 encoding schemes.)
If you specify SHA-1 and 5 bits per character, your session IDs will be 32 characters long because 160 / 5 = 32.
In some cases there are fewer bits left at the end than bits per character, so the last character of the session ID will have a smaller base than the others characters. For example, using MD5 with 5 bits per character yields a 26 character session ID. The first 25 characters can be any one of the base-32 characters, but the final character will be in the range 0-7. This is because 128 / 5 = 25.6. 128 % 5 leaves only 3 bits for the final session ID character, and 2^3 = 8.
The same thing happens when using MD5 with 6 bits per character (the last session ID character will be in the range 0-3) or SHA-1 with 6 bits per character (the last session ID character will be in the hexadecimal range 0-F).
Code: Select all
4 bits/char 5 bits/char 6 bits/char
128-bit digest 32 char SID 26 char SID 22 char SID
160-bit digest 40 char SID 32 char SID 27 char SID- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: length of a session ID ...
By default PHP's session system is very insecure.
First of all, the session identifier PHP generates is not very secure, but should serve its purpose in basic websites. For more paranoid and security important applications, it is a must to have stronger SESSID's. You can customize the behavior of this like already stated in the previous post.
By default, the session identifier is something like this:
The IP address is very potentially known by the attacker and so is the time (e.g. leaked in HTTP) and the microtime is a small factor. The only piece of information that makes it usable is the use of linear congruential generator.
Often when people create own session identifiers in own session systems, they might use something like uniqid() for that. That is not very secure. It's almost the same as the built-in session identifier. uniqid() is similar to this:
At this point you might think that I'm harsh and just throwing thoughts from my head, but believe in me. I know this stuff, I've coded several C++ and Assembly random generators and analyzed how this kind of stuff works. And if you do not believe in my sayings, test yourself by running this code:
You will see something similar to this:
The fact is, whether you use PHP's session system or not, you are often vulnerable to many attacks. For instance, the session storage attacks are very possible in most implementations. There are several things to remember and implementing your own session system is harder than you might think at first; you have to create strong session identifiers, prevent fixations, many kind of hijacking attempts, poisoning attacks, storage attacks, transactional processing must be taken care of, and last, but not least, you have to prevent race conditions and any other potential issues that raised, because of lots of new code you just created.
Even if you use stronger session identifiers and protect from hijacking and fixation, you are still in risk. Also, many applications tend to move their session system into the database. Is that a good approach? That depends entirely how educated the coder was/is.
First of all, the session identifier PHP generates is not very secure, but should serve its purpose in basic websites. For more paranoid and security important applications, it is a must to have stronger SESSID's. You can customize the behavior of this like already stated in the previous post.
By default, the session identifier is something like this:
Code: Select all
$_SERVER['REMOTE_ADDR'].time().microtime().((float) mt_rand()/(float) mt_getrandmax())*10Often when people create own session identifiers in own session systems, they might use something like uniqid() for that. That is not very secure. It's almost the same as the built-in session identifier. uniqid() is similar to this:
Code: Select all
sprintf("%s%08x%05x%.8F",'',$sec,(($usec * 1000000) % 0x100000),((float) mt_rand()/(float) mt_getrandmax())*10)Code: Select all
list($usec, $sec) = explode(' ',microtime());
echo sprintf("%s%08x%05x",'prefix',$sec,(($usec * 1000000) % 0x100000)),'<br>',uniqid('prefix',false);First it ouputs "my own PHP uniqid()", then the PHP's internal uniqid(). The last 2 characters are different, because the microsecond has moved forward because the execution of those functions does not happen so fast.prefix499ca49c6a924
prefix499ca49c6a948
The fact is, whether you use PHP's session system or not, you are often vulnerable to many attacks. For instance, the session storage attacks are very possible in most implementations. There are several things to remember and implementing your own session system is harder than you might think at first; you have to create strong session identifiers, prevent fixations, many kind of hijacking attempts, poisoning attacks, storage attacks, transactional processing must be taken care of, and last, but not least, you have to prevent race conditions and any other potential issues that raised, because of lots of new code you just created.
Even if you use stronger session identifiers and protect from hijacking and fixation, you are still in risk. Also, many applications tend to move their session system into the database. Is that a good approach? That depends entirely how educated the coder was/is.
Re: length of a session ID ...
This might be a good place for me to inject a shameless plug for my FixedBitNotation class, which I posted in the Coding Critique forum but no one commented on.
If you're generating your own random strings using one of the strong techniques Kai talks about all the time, you can use FixedBitNotation to represent it in a customized notation that suits your needs. Whether you're creating unique tokens for use as session IDs, anti-CSRF form IDs, or anything else, I often see people using hexadecimal. Hexadecimal tokens are longer than base-32 or base-64 derived tokens. With FixedBitNotation, you can specify your own arbitrary notation alphabets for your custom unique tokens.
You can also reproduce the exact notation that PHP uses for generating session IDs.André D wrote:The session.hash_bits_per_character setting lets you pick the notation that is used for displaying these 128 or 160-bit hash digests.
- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: length of a session ID ...
I will have a look at it.André D wrote:This might be a good place for me to inject a shameless plug for my FixedBitNotation class, which I posted in the Coding Critique forum but no one commented on.If you're generating your own random strings using one of the strong techniques Kai talks about all the time, you can use FixedBitNotation to represent it in a customized notation that suits your needs. Whether you're creating unique tokens for use as session IDs, anti-CSRF form IDs, or anything else, I often see people using hexadecimal. Hexadecimal tokens are longer than base-32 or base-64 derived tokens. With FixedBitNotation, you can specify your own arbitrary notation alphabets for your custom unique tokens.
You can also reproduce the exact notation that PHP uses for generating session IDs.André D wrote:The session.hash_bits_per_character setting lets you pick the notation that is used for displaying these 128 or 160-bit hash digests.
If you need a cryptographically strong RNG, then either use /dev/random on Unix-like systems or CryptoAPI in Windows based systems. The /dev/urandom is not cryptographically secure, but will do for PHP applications.