Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:73170 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 21032 invoked from network); 14 Mar 2014 23:47:14 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 14 Mar 2014 23:47:14 -0000 Authentication-Results: pb1.pair.com smtp.mail=yohgaki@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=yohgaki@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.217.171 as permitted sender) X-PHP-List-Original-Sender: yohgaki@gmail.com X-Host-Fingerprint: 209.85.217.171 mail-lb0-f171.google.com Received: from [209.85.217.171] ([209.85.217.171:43996] helo=mail-lb0-f171.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 69/51-12876-00593235 for ; Fri, 14 Mar 2014 18:47:13 -0500 Received: by mail-lb0-f171.google.com with SMTP id w7so2243701lbi.16 for ; Fri, 14 Mar 2014 16:47:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=GFaLMliaOLgB+Lg4s830FWu5rj4daXCabdVNbWASllg=; b=zt7v+nqnpO+vEdwBy2+83n74+3nK0e6Y8v8GPAExMhbIvffHXmb0RTP+cNPomEvCIM DSF2ZwrJmxRtJLhlPyrC6TPR7QpRA/k3FyQzbSFZi83454nQI0X/teLXbzRPVODQL9ev d9praN1q8XP0KojmTQ+QWflIpXROnHZZ7cMAbXV1/Hcmdw6BALLtzQJmAGBXKFYcRfB3 HG9eDNkF2azzTWXX6Dv9L0tx/smfRiBrPwfPvYy5cmn/xKL85Qa3rEIgcuzH3F2RFwYq FMCLS34NC7791nHZosZDYcv30jBO5pVpoIa7QJnWRnuSx9hftE2nId0EfEpkl3DSsjQX SyRA== X-Received: by 10.112.26.199 with SMTP id n7mr6975939lbg.27.1394840829630; Fri, 14 Mar 2014 16:47:09 -0700 (PDT) MIME-Version: 1.0 Sender: yohgaki@gmail.com Received: by 10.112.205.73 with HTTP; Fri, 14 Mar 2014 16:46:29 -0700 (PDT) In-Reply-To: <20140314110326.GA80300@mail> References: <20140314074112.GB26909@mail> <20140314110326.GA80300@mail> Date: Sat, 15 Mar 2014 08:46:29 +0900 X-Google-Sender-Auth: JDRamIb5PqYvZaYkjkEgFtaedLw Message-ID: To: Mateusz Kocielski Cc: "internals@lists.php.net" Content-Type: multipart/alternative; boundary=001a113373022b1f3704f499b0df Subject: Re: [PHP-DEV] Solution for session_regenerate_id() issues From: yohgaki@ohgaki.net (Yasuo Ohgaki) --001a113373022b1f3704f499b0df Content-Type: text/plain; charset=UTF-8 On Fri, Mar 14, 2014 at 8:03 PM, Mateusz Kocielski wrote: > 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. > Application means client side application? Suppose you have gallery application that only shows user's photo. Every request for photo should use authenticated session. If session_regenerate_id(TRUE) is called during page rendering, what happens? > 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? > It's explained in previous mail 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. Currently, both user and attacker can use session. > > > 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. > If there is feasible way at session manager level... In user land, there is a way to work round. Developer may implement auto login feature properly and get authentication async way. If auto login is implemented, request with lost session may acquires proper authenticated session via auto login feature. Properly implemented auto login - Must limit exposure of auto login key (i.e. use path parameter for cookie) - Must have long enough random key (i.e. use /dev/urandom and SHA-256 or better) - Must have key usable only once (i.e. Never allow to use the same key multiple times) There could be race condition for auto login key, but client may try to auto login several times. This could be done with AJAX request. This does not work for simple image request/etc, though. > 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. > Of course attacker may, but 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. This is much better than current. Risk is mitigated rather than left open. BTW, almost all security measures are mitigation. 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). I agree. Session manager has to do more, but user code becomes simpler, no need to use AJAX nor time stamp management. If users need more strict HTTP session management like I described, they may implement it by themselves. Regards, -- Yasuo Ohgaki yohgaki@ohgaki.net --001a113373022b1f3704f499b0df--