Cookie token values not random after WtServer restart (leading to hash token collisions)?
Added by Stefan Bn over 4 years 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 over 4 years 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 over 4 years 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 over 4 years 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 over 4 years 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 over 4 years 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 over 4 years 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.