Cookie token values not random after WtServer restart (leading to hash token collisions)?

Added by Stefan Bn 6 months ago

Hi there,

I didn't quite fully understand the behavior of the cookie system (as of Wt 4.1.2). I use the auth, session and cookie implementation completely analog to Wt feature example, no big custom changes.

During development I often kill my MyWtServer process (without dedicated shutdown and cookie removal) and restart it. From time to time I see "hash token collision" errors and was investigating deeper into this.

I see that upon each MyWtServer restart it generates exactly the same random token sequence in AuthService::createAuthToken.

Example Process:

1) Run MyWtServer, login and reloading session three times. Cookie Token Values:
EcZc5Kx9oa1j2Ilua3pQ9MupGVbmkDA2
KCj8MSj2GkIDSPw9XTSJU0TrrHRbr1qG
GTOaeqDPMCVMC1dd5hO1YfexODVssopq

2) Logout MyWtServer = Removing Cookie

3) Kill WtServerProcess

4) Restart MyWtServer, login and reloading session three times. Cookie Token Values:
EcZc5Kx9oa1j2Ilua3pQ9MupGVbmkDA2
KCj8MSj2GkIDSPw9XTSJU0TrrHRbr1qG
GTOaeqDPMCVMC1dd5hO1YfexODVssopq

In WRandom.C I see the use of std::random_device without seeding, thus this seems to be expected behavior? Is it really meant that way, that cookie values are the same sequence after each WtServer-Process restart? At least this seems to explain the token hash collision.

What I don't understand: even if I call WApplication::instance()->removeCookie upon shutdown, the token remains in my Sqlite database table 'auth_token'. When is this token removed from the database normally?

(I did built Wt 4.2.0 and instead of token hash collision my WtServer crashes instantly. I need to investigate deeper. But was something changed in Wt 4.2.0 regarding this?)

Thanks,
Stefan


Replies (6)

RE: Cookie token values not random after WtServer restart (leading to hash token collisions)? - Added by Wim Dumon 6 months ago

Hello Stefan,

What compiler and operating system are you using? While the c++ standard does not impose that std::random_device produces a non-deterministic sequence, we haven't heard of platform on which it does not do so...

Best regards,
Wim.

RE: Cookie token values not random after WtServer restart (leading to hash token collisions)? - Added by Stefan Bn 6 months ago

While the c++ standard does not impose that std::random_device produces
a non-deterministic sequence, we haven't heard of platform on which it does not do so...

I guess now you hear about a (not so unusual) platform that produces deterministic sequences using std::random_device:

All MinGW GCC compilers prior version 9.2 on Windows
(and thus MinGW 7.3.0 64-bit on Windows 10 in my specific case).

https://en.cppreference.com/w/cpp/numeric/random/random_device
Notes: A notable implementation where std::random_device is deterministic is old versions of MinGW (bug 338, fixed since GCC 9.2)

The implementation in WRandom.C thus is based on the assumption that std::random_device always generates non-deterministic sequences. It would be really nice to fix this in WRandom.C by using std::mt19937 and providing a seed based on current time for all MinGW users that could not switch compilers so easily ;-/

Thanks,
Stefan

RE: Cookie token values not random after WtServer restart (leading to hash token collisions)? - Added by Roel Standaert 6 months ago

I read that but didn't notice the part where it says fixed since 9.2. That's pretty recent. I though that old meant really old. Do you need to stay on that version? Maybe we can just say we'll use boost::random_device with older MinGW. mt19937 is no good for generating session ids and tokens on all of the platforms that do have a proper random_device.

RE: Cookie token values not random after WtServer restart (leading to hash token collisions)? - Added by Stefan Bn 6 months ago

From my perspective as a Wt framework user I don't have any influence on that randomization process (or just by moving to another compiler). So maybe one way would be at least to use mt19937 for the "older" MinGW versions <9.2?

Maybe boost is feasible as well but I thought (and hope :-) the Wt framework more and more moves completely away from boost due to all the new C++14/17 features. So I would at least not introduce new boost code into the framework :-)

RE: Cookie token values not random after WtServer restart (leading to hash token collisions)? - Added by Wim Dumon 6 months ago

Hello Stefan,

That's true, in the sense that we prefer to use standard C++ features above boost, if possible. Unfortunately this is a case where we may need to reconsider, since this seems to be a design flaw in the C++ standard... at least the boost random is guaranteed to provide a non-deterministic sequence, or the library does not exist for the platform ("For those environments where a non-deterministic random number generator is not available, class random_device must not be implemented."). Offering a compile-time choice (when Wt is built) to use std::random_device or boost::random_device would be a solution. Not sure if we should/can even implement a check if std::radom_device seems to be working as expected.

Note that mt19937 is not the solution since it requires non-deterministic seeding, which puts us back at square one: source of randomness needed, and std::random_device is no good. So where to get the seed value from? boost::random? :)

RE: Cookie token values not random after WtServer restart (leading to hash token collisions)? - Added by Stefan Bn 6 months ago

Thanks for the insights! I always thought seeding random generators with current date and time provides a sufficient base for non-deterministic random sequences (given that we don't do hard crypto-things here and "just" use it for session and cookie IDs, but maybe I'm wrong). At least we would achive a better state than the current situation.

(1-6/6)