You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by "Craig R. McClanahan" <cr...@apache.org> on 2001/09/13 05:20:28 UTC

[Tomcat 4] Initializing PRNGs for Session Identifiers

Christopher Cain has raised some concerns (both in private email and
publicly on this list) regarding the initialization of pseudo random
number generators (PRNGs) used to calculate session id values.  We need to
have a quick discussion about this, to determine whether we want to change
the current approach.  The purpose of this particular mail thread is to
decide what to do for Tomcat 4 -- developers on the other versions are
welcome to chip in and describe what they do, and what their preferences
might be as well.

BACKGROUND:

Tomcat 4 uses an instance of java.security.SecureRandom to generate
session identifiers for a particular session.  The instance is initialized
the first time (after Tomcat is started, or after a webapp is restarted)
that a session identifier is requested.  The issue at hand for this
discussion is the mechanism used to seed the random number generator
instance.  (If the seed is predicatable, then the entire sequence of
session ids that will be generated is also predictable, which is a nasty
security risk.)

The default seeding algorithm (i.e. if you do not seed it yourself)
gathers system entropy information based on current system activity.  The
good news is that this tends to create a very random starting value.  The
bad news is that it can take many seconds to calculate, with noticeable
impact on the response time for the first session-related request.

To ameliorate this, Tomcat 4 seeds the random number generator based on a
combination of:

* The current timestamp (in milliseconds) when the first request for
  a session id for this web app occurs

* An optional entropy-increasing string value that you can specify
  in your "conf/server.xml" file, like this:

    <Context ...>
        ...
        <Manager entropy="My Private Entropy String"/>
        ...
    </Context>

  If no entropy property is specified, a default (and therefore
  predictable) entropy string is used.

This approach has the advantage of seeding much more quickly, but the
disadvantage that the sequence of session ids is potentially predicatable.
Predicatability is *much* easier if an attacker can manage to read
"conf/server.xml" (although, as I've pointed out to Christopher, security
of your session ids is the *least* of your problems if this happens).  The
current approach is also the one that was recommended the last time this
issue was raised (when Tomcat 3.1 had a *very* weak approach to
calculating session ids).

The decision we face, of course, is whether or not to change this.  A
complicating factor is that some platforms offer facilities (such as
/dev/random) to take advantage of entropy gathered by the OS -- but such
things are obviously not portable, so they cannot be relied on to satisfy
all requiremnts.

It seems to me we have a number of overlapping decisions.  My thoughts are
after each decision area -- I'm looking for input from others.


DECISION 1 - WHAT SEEDING MECHANISMS SHOULD WE SUPPORT?

(1A) Default seeding of java.security.SecureRandom (time consuming but
     reasonably secure)

(1B) Current mechanism of timestamp + entropy string (very fast,
     potentially not secure)

(1C) Plug-in seeding API to allow use of platform-specific algorithms
     if desired

Currently, Tomcat 4 only supports (1B).  It certainly makes sense to offer
(1A) as well.  Offering (1C) is more work, but is not conceptually
difficult.


DECISION 2 - WHAT SEEDING MECHANISM SHOULD BE THE DEFAULT?
  (assumes, of course, that we support them both)

(2A) Default seeding

(2B) Current mechanism

Currently, (2B) is supported, because only (1B) is supported.  This is
likely to be a much more involved discussion that Decision 1.  I could be
persuaded to (2A), but I'm not really certain that this is an issue in the
majority of Tomcat installations -- if we allow people who care about it
to choose (2A), but not make people suffer when they don't feel session id
predicatability is an issue, that seems like a reasonable approach.


DECISION 3 - WHAT PLUG-INS FOR (1C) SHOULD WE OFFER AS STANDARD?

(3A) Unix systems /dev/random

(3B) Unix systems /dev/urandom

(3C) ???

Currently, none of these are supported.


Craig McClanahan



Re: [Tomcat 4] Initializing PRNGs for Session Identifiers

Posted by Christopher Cain <cc...@mhsoftware.com>.
Sorry for the late reply. I was offline for a few days. More below ...

Craig R. McClanahan wrote:

[snip]

 > DECISION 1 - WHAT SEEDING MECHANISMS SHOULD WE SUPPORT?
 >
 > (1A) Default seeding of java.security.SecureRandom (time consuming but
 >      reasonably secure)
 >
 > (1B) Current mechanism of timestamp + entropy string (very fast,
 >      potentially not secure)
 >
 > (1C) Plug-in seeding API to allow use of platform-specific algorithms
 >      if desired
 >
 > Currently, Tomcat 4 only supports (1B).  It certainly makes sense to 
offer
 > (1A) as well.  Offering (1C) is more work, but is not conceptually
 > difficult.

IMHO, and as Craig points out, offering 1A only makes sense. Allowing
for a "maximum security" configuration, given that the changes necessary
to make it an option are trivial, is a no-brainer.

I really dig 1C as well, and I'll help put it together. As Remy said, we
can pursue this once RC1 is out the door.

 > DECISION 2 - WHAT SEEDING MECHANISM SHOULD BE THE DEFAULT?
 >   (assumes, of course, that we support them both)
 >
 > (2A) Default seeding
 >
 > (2B) Current mechanism
 >
 > Currently, (2B) is supported, because only (1B) is supported.  This is
 > likely to be a much more involved discussion that Decision 1.  I could be
 > persuaded to (2A), but I'm not really certain that this is an issue 
in the
 > majority of Tomcat installations -- if we allow people who care about it
 > to choose (2A), but not make people suffer when they don't feel 
session id
 > predicatability is an issue, that seems like a reasonable approach.

I would argue that allowing it to self-seed at container startup time is
also not really an issue in the majority of installations (although I'm
sure I'll hear some disagreement on that one :-)  In production, how
often is the container restarted? And in development, if reloading is
working, how often then?

Since the mechanism for toggling between the slower self-seeding and the 
faster current mechanism will presumably be as easy as changing a value 
in server.xml, it would be simple enough to change it in a develop 
environment where you find yourself restarting often. My feeling is that 
  minor startup delays in a production system are usually unimportant, 
especially if you are trading up for ultra-security.

The current implementation seems reasonably secure, to be fair, but it 
is not a common approach that has been picked over by cryptoanalysts for 
years, whereas the system entropy routines are. The truth is, it is 
impossible to say with near certainty that the current approach is 
cryptographically secure, whereas I *can* make that statement about 
entropy. My opinion is to err on the side of caution, given how 
devasting a weakness in session IDs would be. As a general rule of 
thumb, I prefer to ship with the tightest possible configuration, then 
let users tweak for performance as necessary. If they don't even notice 
the delay, either because their hardware is killer or because they don't 
restart that much, then why even worry about? The ones that do notice 
will look in the docs, and in server.xml itself, and realize that they 
can change it to be faster. It just seems safer to default it to a 
proven approach for people who just want to run the install, fire it up, 
and let it run.

Finally, JDK1.4 is slated to have a *much* faster self-seeding 
mechanism, since the current one is gratuitously slow even for what it 
has to do. At some point in the near future, then, SecureRandom is going 
to get much faster. So why not just change the default before the 4.0 
product goes final, since that will be the obvious default when the JDK 
  gets faster?

 > DECISION 3 - WHAT PLUG-INS FOR (1C) SHOULD WE OFFER AS STANDARD?
 >
 > (3A) Unix systems /dev/random
 >
 > (3B) Unix systems /dev/urandom
 >
 > (3C) ???
 >
 > Currently, none of these are supported.

The Unix plug-ins would be quite easy to write. Windoze doesn't store 
any pre-cached system entropy (which is essentially what the 
random/urandom devices are), so until they do, there's really no way to 
speed things up on that platform.

Dunno about Mac. Since OSX is based on the Mach kernel, chances are that 
the OS stashes some entropy in a similar way to random devices, so a 
plug-in for that is probably quite doable. I have no earthly idea about 
the older Mac OSes =)

- Christopher

/**
   * Pleurez, pleurez, mes yeux, et fondez vous en eau!
   * La moitiƩ de ma vie a mis l'autre au tombeau.
   *    ---Corneille
   */



Re: [Tomcat 4] Initializing PRNGs for Session Identifiers

Posted by Bojan Smojver <bo...@binarix.com>.
"Craig R. McClanahan" wrote:
> 
> Christopher Cain has raised some concerns (both in private email and
> publicly on this list) regarding the initialization of pseudo random
> number generators (PRNGs) used to calculate session id values.  We need to
> have a quick discussion about this, to determine whether we want to change
> the current approach.  The purpose of this particular mail thread is to
> decide what to do for Tomcat 4 -- developers on the other versions are
> welcome to chip in and describe what they do, and what their preferences
> might be as well.
> 
> BACKGROUND:
> 
> Tomcat 4 uses an instance of java.security.SecureRandom to generate
> session identifiers for a particular session.  The instance is initialized
> the first time (after Tomcat is started, or after a webapp is restarted)
> that a session identifier is requested.  The issue at hand for this
> discussion is the mechanism used to seed the random number generator
> instance.  (If the seed is predicatable, then the entire sequence of
> session ids that will be generated is also predictable, which is a nasty
> security risk.)
> 
> The default seeding algorithm (i.e. if you do not seed it yourself)
> gathers system entropy information based on current system activity.  The
> good news is that this tends to create a very random starting value.  The
> bad news is that it can take many seconds to calculate, with noticeable
> impact on the response time for the first session-related request.
> 
> To ameliorate this, Tomcat 4 seeds the random number generator based on a
> combination of:
> 
> * The current timestamp (in milliseconds) when the first request for
>   a session id for this web app occurs
> 
> * An optional entropy-increasing string value that you can specify
>   in your "conf/server.xml" file, like this:
> 
>     <Context ...>
>         ...
>         <Manager entropy="My Private Entropy String"/>
>         ...
>     </Context>
> 
>   If no entropy property is specified, a default (and therefore
>   predictable) entropy string is used.
> 
> This approach has the advantage of seeding much more quickly, but the
> disadvantage that the sequence of session ids is potentially predicatable.
> Predicatability is *much* easier if an attacker can manage to read
> "conf/server.xml" (although, as I've pointed out to Christopher, security
> of your session ids is the *least* of your problems if this happens).  The
> current approach is also the one that was recommended the last time this
> issue was raised (when Tomcat 3.1 had a *very* weak approach to
> calculating session ids).
> 
> The decision we face, of course, is whether or not to change this.  A
> complicating factor is that some platforms offer facilities (such as
> /dev/random) to take advantage of entropy gathered by the OS -- but such
> things are obviously not portable, so they cannot be relied on to satisfy
> all requiremnts.
> 
> It seems to me we have a number of overlapping decisions.  My thoughts are
> after each decision area -- I'm looking for input from others.
> 
> DECISION 1 - WHAT SEEDING MECHANISMS SHOULD WE SUPPORT?
> 
> (1A) Default seeding of java.security.SecureRandom (time consuming but
>      reasonably secure)
> 
> (1B) Current mechanism of timestamp + entropy string (very fast,
>      potentially not secure)
> 
> (1C) Plug-in seeding API to allow use of platform-specific algorithms
>      if desired
> 
> Currently, Tomcat 4 only supports (1B).  It certainly makes sense to offer
> (1A) as well.  Offering (1C) is more work, but is not conceptually
> difficult.
> 
> DECISION 2 - WHAT SEEDING MECHANISM SHOULD BE THE DEFAULT?
>   (assumes, of course, that we support them both)
> 
> (2A) Default seeding
> 
> (2B) Current mechanism
> 
> Currently, (2B) is supported, because only (1B) is supported.  This is
> likely to be a much more involved discussion that Decision 1.  I could be
> persuaded to (2A), but I'm not really certain that this is an issue in the
> majority of Tomcat installations -- if we allow people who care about it
> to choose (2A), but not make people suffer when they don't feel session id
> predicatability is an issue, that seems like a reasonable approach.
> 
> DECISION 3 - WHAT PLUG-INS FOR (1C) SHOULD WE OFFER AS STANDARD?
> 
> (3A) Unix systems /dev/random
> 
> (3B) Unix systems /dev/urandom
> 
> (3C) ???
> 
> Currently, none of these are supported.
> 
> Craig McClanahan

Some of that stuff has been implemented in Tomcat 3.3 (3.x?). The file
SessionIdGenerator.java should be able to explain how TC 3.3 handles
those issues.

>From memory, there was a discussion about using /dev/urandom on this
list in relation to Tomcat 3.x (search for '/dev/urandom' and/or
'SessionIdGenerator' on this list) and also the differences of it as
compared to /dev/random. Doug Barnes nicely explained a lot of that
stuff. This can also be helpful.

In practice, having /dev/urandom helping with session ID's is essential.
It speeds up Tomcat significantly.

Also, if you inspect the above mentioned code, you'll notice that if
platform specific instrumentation is not available, Tomcat 3.3 will
default to the same thing in Java world, which is
java.security.SecureRandom.

Bojan

Re: [Tomcat 4] Initializing PRNGs for Session Identifiers

Posted by Remy Maucherat <re...@apache.org>.
> BACKGROUND:

> * An optional entropy-increasing string value that you can specify
>   in your "conf/server.xml" file, like this:
>
>     <Context ...>
>         ...
>         <Manager entropy="My Private Entropy String"/>
>         ...
>     </Context>
>
>   If no entropy property is specified, a default (and therefore
>   predictable) entropy string is used.
>
> This approach has the advantage of seeding much more quickly, but the
> disadvantage that the sequence of session ids is potentially predicatable.
> Predicatability is *much* easier if an attacker can manage to read
> "conf/server.xml" (although, as I've pointed out to Christopher, security
> of your session ids is the *least* of your problems if this happens).  The
> current approach is also the one that was recommended the last time this
> issue was raised (when Tomcat 3.1 had a *very* weak approach to
> calculating session ids).
>
> The decision we face, of course, is whether or not to change this.  A
> complicating factor is that some platforms offer facilities (such as
> /dev/random) to take advantage of entropy gathered by the OS -- but such
> things are obviously not portable, so they cannot be relied on to satisfy
> all requiremnts.
>
> It seems to me we have a number of overlapping decisions.  My thoughts are
> after each decision area -- I'm looking for input from others.
>
>
> DECISION 1 - WHAT SEEDING MECHANISMS SHOULD WE SUPPORT?
>
> (1A) Default seeding of java.security.SecureRandom (time consuming but
>      reasonably secure)
>
> (1B) Current mechanism of timestamp + entropy string (very fast,
>      potentially not secure)

I think the current mechanism is good enough. With a carefully chosen
secret, I don't see how that could be cracked, and if it turns out it's
actually doable, it must be a lot easier to try to find another way in.

Also, maybe we can find a way to slightly improve the randomness of the
seed.

> (1C) Plug-in seeding API to allow use of platform-specific algorithms
>      if desired

The plugin mechanism looks like a very good idea, and we should implement it
in the next maintenance release of Tomcat 4.

> Currently, Tomcat 4 only supports (1B).  It certainly makes sense to offer
> (1A) as well.  Offering (1C) is more work, but is not conceptually
> difficult.
>
>
> DECISION 2 - WHAT SEEDING MECHANISM SHOULD BE THE DEFAULT?
>   (assumes, of course, that we support them both)
>
> (2A) Default seeding
>
> (2B) Current mechanism
>
> Currently, (2B) is supported, because only (1B) is supported.  This is
> likely to be a much more involved discussion that Decision 1.  I could be
> persuaded to (2A), but I'm not really certain that this is an issue in the
> majority of Tomcat installations -- if we allow people who care about it
> to choose (2A), but not make people suffer when they don't feel session id
> predicatability is an issue, that seems like a reasonable approach.

The security level provided by 2B seems enough in 99% of the cases, so I
would leave it as the default.

> DECISION 3 - WHAT PLUG-INS FOR (1C) SHOULD WE OFFER AS STANDARD?
>
> (3A) Unix systems /dev/random
>
> (3B) Unix systems /dev/urandom
>
> (3C) ???
>
> Currently, none of these are supported.

We probably will have to start a modules repository to put that kind of
additional features.

Remy