Re: [VOTE] Secure Session Module Options/Internal by Default

From: Date: Tue, 18 Feb 2014 10:42:39 +0000
Subject: Re: [VOTE] Secure Session Module Options/Internal by Default
References: 1 2 3 4 5 6 7  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Hi Stas,

On Tue, Feb 18, 2014 at 1:11 PM, Stas Malyshev <[email protected]>wrote:

> > When "use_strict_mode=on", attacker sends short session ID many times to
> > see if the char matches part of session ID or not. When underlying data
> > storage is vulnerable to timing attack, timing is leaked. i.e.
> > stat(session_data_file_name) could be timing unsafe.
>
> Why would they send short ID if they could send full-length ID and
> easily defeat your checks?
>

3 reasons.
 - Hash used by session may fallback to SHA-1 from SHA-256
 - User may set hash to SHA-1 or md5 by mistake or intentionally
 - 23 chars would be enough for timing attack counter measure

23 chars works with md5 and hash_bits_per_character=6 also.

> htree is safe.  Weak hash could be issue. Most of us remember hash
> > collision attack few years ago. (e.g mm save handler uses very simple
>
> Hash collistion attacks have nothing to do with this, they rely on the
> fact that hash we are using is not perfect and it is easy to generate
> colliding strings, thus producing degenerate performance. However, in
> this case we're talking about completely different scenario.
>
> > With minimum length, attacker must guess char combinations of that
> > length regardless of underlying session data storage.
>
> Not really. The whole point of timing attack is that the underlying
> mechanism must not use all chars of the string for comparison.
>
> > Minimum session ID length solves all issues/anxieties and we may leave
> > timing attack behind as long as users set appropriate value to it.
>
> I still don't see even one issue it solves. Timing attack would still
> work the same if underlying mechanism uses comparison where time of
> comparing aaaa to bbbb (assuming length is 4) if different from timing
> of comparing aaaa to aaab. Different length is not required here, and
> since length is public, it won't be the factor in the attack anyway.


When minimum ID length is used, session module discards shorter session ID
immediately. It does not ask save handlers to check ID at all. i.e. No
stat(session_data_file) nor query to database. It creates new ID before it.

Therefore, attacker must guess random string up to minimum ID length. It is
safe with the same reason for timing safe string comparison.

if (strlen(a) != strlen(b)) {
  // It leaks length, but this is timing safe, since it's not comparing
string at all.
  return FAILURE;
 }
if (!timing_safe_compare(a, b, len)) {
  return FAILURE;
}
return SUCCESS;

Minimum ID length would do something like

if (min_id_len > strlen(session_id_string)) {
   // Timing safe up to min_id_len because it's not comparing string up to
min_id_len.
   create_new_id(); // Discard invalid ID and create new ID
}
start_initialize_session(); // Call save handlers

User land solution is possible. To do the same job as session module, user
has to check $_COOKIE, $_GET and $_POST before calling session_start() to
see if session ID is in there according to session related INI. If there
is, check supplied session ID is longer than minimum ID length. If it's
invalid, generate secure session ID and set it via session_id(). Finally,
call session_start().

We don't have API for generating secure session ID currently also. This
would be too much for users to make session timing safe.

Regards,

--
Yasuo Ohgaki
[email protected]


Thread (19 messages)

« previous php.internals (#72677) next »