Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:73161 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69855 invoked from network); 14 Mar 2014 11:03:32 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 14 Mar 2014 11:03:32 -0000 Authentication-Results: pb1.pair.com header.from=shm@digitalsun.pl; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=shm@digitalsun.pl; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain digitalsun.pl from 176.31.254.40 cause and error) X-PHP-List-Original-Sender: shm@digitalsun.pl X-Host-Fingerprint: 176.31.254.40 turing.digitalsun.pl Received: from [176.31.254.40] ([176.31.254.40:51250] helo=mail) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C7/50-02580-202E2235 for ; Fri, 14 Mar 2014 06:03:32 -0500 Received: from localhost (10000@localhost [local]); by mail (OpenSMTPD) with ESMTPA id 84a2a6a7; Fri, 14 Mar 2014 11:03:26 +0000 (UTC) Date: Fri, 14 Mar 2014 11:03:26 +0000 To: Yasuo Ohgaki Cc: "internals@lists.php.net" Message-ID: <20140314110326.GA80300@mail> References: <20140314074112.GB26909@mail> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [PHP-DEV] Solution for session_regenerate_id() issues From: shm@digitalsun.pl (Mateusz Kocielski) Hello, On Fri, Mar 14, 2014 at 06:37:35PM +0900, Yasuo Ohgaki wrote: > On Fri, Mar 14, 2014 at 4:41 PM, Mateusz Kocielski wrote: > > > I'm not sure if we should handle that in PHP, application usually > > regenerates > > session on important events (i.e. on user login/logout etc.), so any > > requests > > with old session should be denied, and this can be achieved using > > session_regenerate_id(TRUE). Wouldn't it be better to write a security > > note in the documentation rather than making whole thing more complex? > > > > The issue is that session_regenerate_id(TRUE) is unreliable. It could cause > race condition since requests from client are not synchronized. There is no > way to force synchronized access resources to clients. Out of sync issue > would be more noticeable under mobile environment, networks with poor > congestion control and/or the same web app in multiple tabs. I don't see why we should be so worried about it. Answer from server could not be delivered, thousand things can simply go wrong, all those "exceptions" should be handled by the application. > Users may set timeout flag in $_SESSION array and check the value if > session could be active or not. In order to do that in user land, one may do > > session_start() > // ** check timeout flag ** > if (!empty($_SESSION['VALID_UNTIL']) && $_SESSION['VALID_UNTIL'] < time()) { > session_destroy(); > trigger_error('Possible session hijack attack detected'); > die('Possible session hijack attack detected'); > } > > // ** set timeout flag ** > if ($_SESSION['LAST_REGENERATE'] < time() + 600) { > $_SESSION['VALID_UNTIL'] = time() + 60; // Shorter is better, but rather > large value is set for lost radio/hand over/etc. Old session is allowed to > use as valid session for 60 seconds. > session_commit(); // Need to save above data in old session. > session_start(); > $_SESSION['LAST_REGENERATE'] = time(); // Update regenerate time here. > session_regenerate_id(); // New session ID and old session data with old > session ID is left > unset($_SESSION['VALID_UNTIL']; // This session should not be deleted > later. > } > > > Something like this should be done for reliable session_regenerate_id(). I > think not many apps do this. > > Above example is allowing 60 seconds window for legitimate user and > attacker. If session is hijacked, > - User could know attack if session ID is regenerated by attacker. > - Attacker could know there is hijack protection if session ID is > regenerated by user. > > Without code like above, both attacker and user may use the session as long > as web app allows. User has no chance to know if he/she is under session > hijack attack or not. Attacker feels safe to enjoy stolen session. Every pot has two handles, user has no chance to know is he/she is under session attack, but also server doesn't know who's the attacker and who's the victim. What if we'll regenerate session upon attacker's request? > This should be session manager task and calling session_regenerate_id() > should be enough for PHP users, IMO. I see your arguments valid, but I feel that it's sweeping under the rug the real problem, which is handling async requests properly. > I didn't include automatic session ID regeneration in the RFC, but it could > be handled by session manager also. It's just a matter of storing/checking > last regenerate time. If users are following security best practices, they > should renew session ID periodically even when HTTPS is used. Is periodically renewing session ID really a big benefit? If an attacker can obtain session id from victim once, then with probability ~1 session can be stolen again. BTW, don't get me wrong, I'm not against making PHP more secure, I just want to keep things as simple as possible (which is usually good for security too). Regards, Mateusz Kocielski