Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:95104 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 88464 invoked from network); 12 Aug 2016 20:39:30 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 12 Aug 2016 20:39:29 -0000 Authentication-Results: pb1.pair.com header.from=yohgaki@ohgaki.net; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=yohgaki@ohgaki.net; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain ohgaki.net designates 180.42.98.130 as permitted sender) X-PHP-List-Original-Sender: yohgaki@ohgaki.net X-Host-Fingerprint: 180.42.98.130 ns1.es-i.jp Received: from [180.42.98.130] ([180.42.98.130:55348] helo=es-i.jp) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id BC/E3-55605-EF33EA75 for ; Fri, 12 Aug 2016 16:39:28 -0400 Received: (qmail 126410 invoked by uid 89); 12 Aug 2016 20:39:22 -0000 Received: from unknown (HELO mail-qk0-f180.google.com) (yohgaki@ohgaki.net@209.85.220.180) by 0 with ESMTPA; 12 Aug 2016 20:39:22 -0000 Received: by mail-qk0-f180.google.com with SMTP id v123so36225977qkh.2 for ; Fri, 12 Aug 2016 13:39:22 -0700 (PDT) X-Gm-Message-State: AEkooutLjyT2vJ7UdbN/V40L9JYhczu1Liq8yHrVLJhJa2Rx6TZzpFv5Az3X2v9QGgH35AaAT3TEHTUIwWrBpg== X-Received: by 10.55.135.198 with SMTP id j189mr3094714qkd.60.1471034355226; Fri, 12 Aug 2016 13:39:15 -0700 (PDT) MIME-Version: 1.0 Received: by 10.140.85.242 with HTTP; Fri, 12 Aug 2016 13:38:34 -0700 (PDT) In-Reply-To: References: Date: Sat, 13 Aug 2016 05:38:34 +0900 X-Gmail-Original-Message-ID: Message-ID: To: Tom Worster Cc: Leigh , "internals@lists.php.net" Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] [RFC][VOTE] Add session_create_id() function From: yohgaki@ohgaki.net (Yasuo Ohgaki) Hi Tom, On Sat, Aug 13, 2016 at 3:11 AM, Tom Worster wrote: > On 8/11/16 6:58 PM, Yasuo Ohgaki wrote: >> >> Hi Leigh, >> >> On Fri, Aug 12, 2016 at 3:25 AM, Leigh wrote: >>> >>> On Wed, 10 Aug 2016 at 10:15 Yasuo Ohgaki wrote: >>>> >>>> >>>> Hi all, >>>> >>>> This is RFC for adding session_create_id() function. >>>> >>>> Session ID string uses special binary to string conversion. Users >>>> should write lengthy and slow code to have the same session ID string >>>> as session module does. >>> >>> >>> >>> I disagree, this pretty much covers it: >>> >>> function session_create_id() >>> { >>> $encoded = base64_encode(random_bytes(random_bytes(32))); >>> // Use same charset as PHP >>> return rtrim(strtr($encoded, '+/', ',-'), '='); >>> } >> >> >> Thank you for insight! >> >> You've missed to set SID to proper length and SID validation. > > > Replacing rtrim() with substr() is fixes that. No. Base 64 adds padding for extra bytes. The Padding char is "=" and it's illegal char as SID. Therefore trims is mandatory. Don't you think it's nice to make "PHP just works" without knowing such details? > > >> function session_create_id(string $prefix) >> { >> $encoded = base64_encode(ini_get('session.sid_length')*2); > > > Did you omit random_bytes() in this line? I don't why I did this :) I thought I replaced "32" to ini setting. > > >> // Use same charset as PHP >> $sid = substr(rtrim(strtr($encoded, '+/', ',-'), '='), 0, >> ini_get('session.sid_length'); >> >> $sid .= $prefix; >> >> // Now validate SID so that it does not have collisions >> when session is active, connect to database and validate SID >> try to fetch sid >> if sid is not there >> try again to generate SID few times >> if SID validation failed >> fatal error >> return safe SID >> when session is inactive >> return unvalidated SID >> } >> >> This is what proposed session_create_id() does. >> I used pseudo, but it should be easy to imagine it would be lengthy code. > > > You don't need to waste time checking for collisions if the SID has a random > component of sufficient length. 32 random base-64 characters is sufficient. > > There are lots of purposes for random strings with negligible chance of > collision. Hence some frameworks provide the function, e.g. > http://www.yiiframework.com/doc-2.0/yii-base-security.html#generateRandomString()-detail > > Only the search of the the session database for collisions seems hard to me. > But I don't understand why it is needed. Session ID security is key factor of Web application security. There is huge difference between 'cannot happen' and 'very rare and almost cannot happen'. In addition, proving 'very rare and almost cannot happen' is difficult. NIST requires SHA2 or better hash for collision sensitive usage. SHA2 has 256 bits or more. We only use 128 bits, i.e. MD5 and bits_per_character=5 now. (130 bits for 7.1 and later). Therefore, I don't think collision check is needless. We should have 256 bits session ID at least which requires 52 chars with 5 bits_per_character. We know it's relatively easy to check if a PRNG meets NIST requirement, but requirement fulfillment does not mean PRNG is generating excellent random. Measuring quality of PRNG is difficult. (This does not mean we should add low quality entropy such as time and pid to create SID and hash it. We depends on PRNG security anyway, use of hash and low quality entropy only makes SID weaker. Thus I proposed raw PRNG usage for SID) These things make me think collision detection is mandatory to say "PHP session is secure". Anyway, I'm not a cryptographer and just following their advices. I suggest you do the same. Regards, -- Yasuo Ohgaki yohgaki@ohgaki.net