-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Remove hash usage from session ID creation #1850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Yasuo, seems you include the stuff planned in #1769, but also some more as per RFC. IMHO replacing the current parts with php_random_bytes() were already a good step into the direction, to unify the randomness source for all platforms. I guess this substep wouldn't even require an RFC. Thanks. |
I agree. php_random_bytes() should be used regardless of RFC vote result. I'll make sure it will be in PHP 7.1. |
|
||
return SUCCESS; | ||
} | ||
php_error_docref(NULL, E_WARNING, "session.configuration 'session.sid_length' must between 32 and 256."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a typo? The check above is val >= 22 && val <= PS_MAX_SID_LENGTH
- so the minimum length is 22 not 32?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Newer restriction should be 22!
|
||
php_error_docref(NULL, E_WARNING, "The ini setting hash_bits_per_character is out of range (should be 4, 5, or 6) - using 4 for now"); | ||
/* Read additiona PS_EXTRA_RAND_BYTES just in case CSPRNG is not safe enough */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a typo - should be "additional"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I'll fix this!
session.sid_length = 32 session.sid_bits_per_charactor = 4 However, php.ini-development/production had session.hash_func = 0 (MD5 128) session.hash_bits_per_character = 5 <--- This differs from compiled default. I didn't notice this. This config results in shorter session ID length. (26 chars) Anyway, most PHP installation would have session ID length = 32. So normal(?) users who are using php.ini-production as php.ini would get - session.sid_length=32 - session.sid_bits_per_character=5 and bits in session ID is 160 bits. (Older config was 128 bits)
. session.sid_bits_per_character (Bits used per byte. 4 to 6. Default: 4) | ||
. If you were using session.hash_func=1(SHA1) and session.hash_bits_per_charactor=6 | ||
Use following INIs to achive the same or better session ID strength. | ||
. session.sid_length=32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you note how one needs to calculate the new settings based on the old ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it!
merged. |
@@ -1457,7 +1443,7 @@ session.hash_function = 0 | |||
; Development Value: 5 | |||
; Production Value: 5 | |||
; http://php.net/session.hash-bits-per-character |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The link needs to get updated, but the shortcut http://php.net/session.sid-bits-per-character doesn't seem to exist yet.
; Set session ID character length. This value could be between 22 to 256. | ||
; Shorter length than default is supported only for compatibility reason. | ||
; Users should use 32 or more chars. | ||
; http://php.net/session.sid_length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This URL doesn't exist and shouldn't it use a dash like all the other links?
break; | ||
#endif /* HAVE_HASH_EXT */ | ||
/* Read additional PS_EXTRA_RAND_BYTES just in case CSPRNG is not safe enough */ | ||
if (php_random_bytes_throw(rbuf, PS(sid_length) + PS_EXTRA_RAND_BYTES) == FAILURE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems strange to me that it needs to read so many random bytes. In theory it should only require to read sid_length * sid_bits_per_character / 8
bytes. All the extra bytes read seem wasted. Could you explain why this is done this way?
@Tobion php.ini-* and ini.list.xml is updated now. |
@yohgaki I've read the RFC and the discussion on the mailing list and I don't see how reading extra bytes should "mitigate risks of broken PRNG". If the random bytes are predictable, then reading 60 extra bytes does not make them less predictable. So what's the point? |
@Tobion BTW, magic number "60" is chosen because I would like to read more than 64 bytes addition data from PRNG. i.e. When sid_bits_per_character is 6 and sid_length is 22, (60 bytes + 5.5 bytes(22 bits * 2)) > 64 bytes. |
As far as I see, you are reading |
It's 65.5 bytes (480 bits + 44 bits), not 88 bytes for that case. Anyway, I don't insist to have "extra 60 bytes". It just the code proposed with the RFC and extra bytes are added according to RFC discussion with Stas. (Stas worried about PRNG state exposure) I don't mind removing extra PRNG reads at all indeed. It may hurt performance on some architectures that have slow PRNG generation rate. New code does not use full bits from PRNG and it would be good enough mitigation. IMO. |
Length of old session ID string is determined as follows | ||
. Used hash function's bits. | ||
. session.hash_function=0 - MD5 128 bits (This was default) | ||
. session.hash_function=1 - SHA1 192 bits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sha1 is 160 bits. fixed in #2228
@@ -300,151 +295,24 @@ static char *bin_to_readable(char *in, size_t inlen, char *out, char nbits) /* { | |||
} | |||
|
|||
*out = '\0'; | |||
return out; | |||
return len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why does the method return the length when it is constant? Seems useless.
@yohgaki this |
@Tobion Anyway, the code reads more than enough extra bytes from PRNG to avoid exposing PRNG state. If you would like to remove it, write RFC for it. I wouldn't oppose it. |
This is PR for "Session ID without hashing" RFC.
https://wiki.php.net/rfc/session-id-without-hashing