Bug #75496 [Asn]: Session ID Collision happened few times

From: Date: Wed, 08 Nov 2017 18:58:37 +0000
Subject: Bug #75496 [Asn]: Session ID Collision happened few times
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-212523@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=75496&edit=1 ID: 75496 User updated by: dmitry dot yeskin at gmail dot com Reported by: dmitry dot yeskin at gmail dot com Summary: Session ID Collision happened few times Status: Assigned Type: Bug Package: Session related Operating System: Amazon OS PHP Version: 7.0.25 Assigned To: yohgaki Block user comment: N Private report: N New Comment: In my controller in init() method I added this code for tracking: if (session_status() == PHP_SESSION_NONE) { session_start(); } if (isset($_SESSION['user_agent']) && !empty($_SESSION['user_agent']) && $_SESSION['user_agent'] != Yii::$app->request->getUserAgent()) { $data = 'Session ID: ' . session_id() . "\n" . 'User Agent: ' . Yii::$app->request->getUserAgent() . "\n" . 'IP: ' . Yii::$app->request->getUserIP() . "\n" . 'SESSION: ' . print_r($_SESSION, true); @mail('[MY EMAIL HERE]', 'Session ID Collision', $data); session_regenerate_id(); session_destroy(); session_start(); session_regenerate_id(); unset($_SESSION['user_agent']); $_SESSION['cart'] = array(); unset($_SESSION['cart']); } if (!isset($_SESSION['user_agent'])) { $_SESSION['user_agent'] = Yii::$app->request->getUserAgent(); $_SESSION['ip_address'] = Yii::$app->request->getUserIP(); } So it works like: if you dont have user_agent in your session - it adds it there. And if you have session started but your user_agent is not like one saved in your session (that is what happens when session shared), it send me email with data about "new session owner" and content of session from previous owner (his user_agent and IP) and trying to regenerate session (yes, I do it now 2 times + session_destroy in the middle to more guarantee). So I got today already 5 notifications about session collisions. Here is just example from one of emails: ------- Session ID: Y4gXw2l8fZZRHVgu0KoLamr5ywVyw5UauP0BOKdjpg0 User Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0_3 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Mobile/15A432 [FBAN/FBIOS;FBAV/147.0.0.46.81;FBBV/76961488;FBDV/iPhone9,2;FBMD/iPhone;FBSN/iOS;FBSV/11.0.3;FBSS/3;FBCR/Verizon;FBID/phone;FBLC/en_US;FBOP/5;FBRV/0] IP: 174.200.9.242 SESSION: Array ( [user_agent] => Mozilla/5.0 (Linux; Android 7.0; SM-N920T Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/148.0.0.51.62;] [ip_address] => 172.58.110.205 [__flash] => Array ( ) ) ------ So as described above in code, new customer with IP 174.200.9.242 assigned already existing session ID Y4gXw2l8fZZRHVgu0KoLamr5ywVyw5UauP0BOKdjpg0 which is owned and initiated by customer with IP 172.58.110.205. This can be confirmed with server nginx logs. That already happened 5 times today. I didn't track for collisions before and just had complaints from customers, but I believe that in the past days we had a much more collisions than we think. Right now, I can track every single collision but not sure what to do with this and what is the reason of it. Maybe some RAM memory overload? Maybe CPU overload? Maybe because PHP is working as php-fpm? What can I do more to help identify this issue? Previous Comments: ------------------------------------------------------------------------ [2017-11-08 17:33:11] dmitry dot yeskin at gmail dot com Thanks for comment nikic! It was a good idea but unfortunately looks like thats not a case. I tried this code to verify it: $fp = fopen('/dev/urandom','rb'); if ($fp !== FALSE) { $result = fread($fp, 100); fclose($fp); print $result; } else { die('Can not open /dev/urandom.'); } And I got random string in result. But few minutes ago I got one more collision! So 2 collisions only today!!! Yes traffic is not small - already 430 successful orders this morning. Only 2 collisions. But anyway - thats not normal! And I have all day today session.use_strict_mode enabled after Yasuo Ohgaki comment! Please help. ------------------------------------------------------------------------ [2017-11-08 14:05:20] nikic@php.net Even without an explicit check, random session ID collisions are vanishingly unlikely. Looking at how the session ID generation worked in PHP 7.0 and your configuration, my best guess would be that /dev/urandom is not readable from PHP. In PHP 7.0 this error case is unfortunately silently ignored, while PHP 7.1 will trigger an error. Can you verify that /dev/urandom is readable from PHP? ------------------------------------------------------------------------ [2017-11-08 13:18:12] dmitry dot yeskin at gmail dot com I updated session.use_strict_mode to 1 this mornjng but a fee minutes ago another collision happened again. So strict mode doesnt help. ------------------------------------------------------------------------ [2017-11-08 09:20:41] dmitry dot yeskin at gmail dot com Thanks for your response. It was not an attack. It was 2 old ladies who both bought Christmas postcards for children. Both successfully paid. And both complained that wrong data in their orders. These 2 customers were even anonymous customers - they made orders without any login. Website is simple - you come to postcard page - click "Add to cart", and information about postcard added to user $_SESSION. Then in cart and checkout - they just pay for it and data about order saved to database. Nothing too fancy. I attached code for addToCart method as example. Regarding your question of php.ini settings, here it is: --- session.auto_start Off session.cache_expire 180 session.cache_limiter nocache session.cookie_domain no value session.cookie_httponly On session.cookie_lifetime 0 session.cookie_path / session.cookie_secure On session.entropy_file /dev/urandom session.entropy_length 32 session.gc_divisor 1000 session.gc_maxlifetime 1440 session.gc_probability 1 session.hash_bits_per_character 6 session.hash_function sha256 session.lazy_write On session.name PHPSESSID session.referer_check no value session.save_handler files session.save_path /var/lib/php/7.0/session session.serialize_handler php session.upload_progress.cleanup On session.upload_progress.enabled On session.upload_progress.freq 1% session.upload_progress.min_freq 1 session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS session.upload_progress.prefix upload_progress_ session.use_cookies On session.use_only_cookies On session.use_strict_mode Off session.use_trans_sid 0 --- We really don't have session.use_strict_mode on. But do you think it could be a reason? I thought that PHP must check for session collisions even without it? I mean, purpose of strict mode is to protect site from starting uninitialized sessions. I think thats not a case. Thats more against hackers and hijackings, not about session collisions. Am I wrong? Do you really think it will solve the problem if I enable it? ------------------------------------------------------------------------ [2017-11-08 02:23:05] yohgaki@php.net Could you get session related INI settings by phpinfo() on the server? Thank you. Anyway, it would be some kind of attack most likely. As you may knew already, unremovable cookies are created easily by JS, etc. If you don't have session_regenerate_id() before user authentication flag is set, you(your users) might have been attacked. I strongly suggest to enable session ID collision detection feature (session.use_strict_mode=1) which is disabled by default. Beware that it has some overheads which I would like to eliminate someday. Your code should be prepared for session_start() failure by ID collision. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=75496 -- Edit this bug report at https://bugs.php.net/bug.php?id=75496&edit=1

« previous php.bugs (#212523) next »