Re: random token re-used in subsequent requests
André Warnier <[email protected]>
| Newsgroups | gmane.comp.apache.mod-perl |
|---|---|
| Message-ID | <[email protected]> |
On 17.05.2016 08:28, Vincent Veyron wrote: > On Mon, 16 May 2016 22:45:14 +0000 > "Bruce Johnson" <[email protected]> wrote: > >> >> I don’t think it would be likely for Vincent to ever see this once, let alone have it rise to the issue of a problem if it were strictly about non-randomness of the rand() function. >> > > Indeed : I also use the function to generate cookies; the strings are stored in a database table with a primary key on the token ; running 'ab -c 4 -n 4000 "http://my/url/here"' 3 times yields 12 000 unique keys on a functional server. > > The machine where the error showed up can't get two different strings in a row. It's a backup server, so I'm the only one using it for test purposes, which is why I did not notice the error before; it may have been present for a long time. > > Below is what is installed on each machine, the first one (arsene) being the faulty one; it is a rather old Dell desktop, the others are dedicated servers in datacenters, such as kimsufi.com, online.net. Everything is on bare metal, and incidentally not as uniform as I thought :-( > reload-perl is installed but disabled in apache2.conf > > perl -v on the faulty machine (arsene) : > This is perl 5, version 20, subversion 2 (v5.20.2) built for i586-linux-gnu-thread-multi-64int > perl -v on the good ones : > This is perl 5, version 20, subversion 2 (v5.20.2) built for x86_64-linux-gnu-thread-multi > > > arsene (cpuinfo : Intel(R) Core(TM)2 Duo CPU E7500 @ 2.93GHz) > ii apache2 2.4.10-10+deb8u4 i386 Apache HTTP Server > ii apache2-bin 2.4.10-10+deb8u4 i386 Apache HTTP Server (modules and other binary files) > ii apache2-data 2.4.10-10+deb8u4 all Apache HTTP Server (common files) > ii apache2-mpm-prefork 2.4.10-10+deb8u4 i386 transitional prefork MPM package for apache2 > ii apache2-utils 2.4.10-10+deb8u4 i386 Apache HTTP Server (utility programs for web servers) > ii apache2.2-common 2.4.10-10+deb8u4 i386 Transitional package for apache2 > ii libapache2-mod-apreq2 2.13-4+b1 i386 generic Apache request library - Apache module > ii libapache2-mod-perl2 2.0.9~1624218-2+deb8u1 i386 Integration of perl with the Apache2 web server > ii libapache2-reload-perl 0.12-3 all module for reloading Perl modules when changed on disk > ii libapache2-request-perl 2.13-4+b1 i386 generic Apache request library - Perl modules > > kimsufi (cpuinfo : Intel(R) Atom(TM) CPU N2800 @ 1.86GHz) > ii apache2 2.4.10-10+deb8u4 amd64 Apache HTTP Server > ii apache2-bin 2.4.10-10+deb8u4 amd64 Apache HTTP Server (modules and other binary files) > ii apache2-data 2.4.10-10+deb8u4 all Apache HTTP Server (common files) > ii apache2-mpm-prefork 2.4.10-10+deb8u4 amd64 transitional prefork MPM package for apache2 > ii apache2-utils 2.4.10-10+deb8u4 amd64 Apache HTTP Server (utility programs for web servers) > ii apache2.2-common 2.4.10-10+deb8u4 amd64 Transitional package for apache2 > ii libapache2-mod-apreq2 2.13-4+b1 amd64 generic Apache request library - Apache module > ii libapache2-mod-perl2 2.0.9~1624218-2+deb8u1 amd64 Integration of perl with the Apache2 web server > ii libapache2-reload-perl 0.12-3 all module for reloading Perl modules when changed on disk > ii libapache2-request-perl 2.13-4+b1 amd64 generic Apache request library - Perl modules > > online (cpuinfo : VIA Nano processor U2250 (1.6GHz Capable)) > ii apache2 2.4.10-10+deb8u4 amd64 Apache HTTP Server > ii apache2-bin 2.4.10-10+deb8u4 amd64 Apache HTTP Server (modules and other binary files) > ii apache2-data 2.4.10-10+deb8u4 all Apache HTTP Server (common files) > ii apache2-mpm-prefork 2.4.10-10+deb8u4 amd64 transitional prefork MPM package for apache2 > ii apache2-utils 2.4.10-10+deb8u4 amd64 Apache HTTP Server (utility programs for web servers) > ii libapache2-mod-apreq2 2.13-4+b1 amd64 generic Apache request library - Apache module > ii libapache2-mod-perl2 2.0.9~1624218-2+deb8u1 amd64 Integration of perl with the Apache2 web server > ii libapache2-request-perl 2.13-4+b1 amd64 generic Apache request library - Perl modules > > ovh (cpuinfo : Intel(R) Celeron(R) CPU 220 @ 1.20GHz) > ii apache2 2.4.10-10+deb8u4 amd64 Apache HTTP Server > ii apache2-bin 2.4.10-10+deb8u4 amd64 Apache HTTP Server (modules and other binary files) > ii apache2-data 2.4.10-10+deb8u4 all Apache HTTP Server (common files) > ii apache2-utils 2.4.10-10+deb8u4 amd64 Apache HTTP Server (utility programs for web servers) > ii libapache2-mod-apreq2 2.13-4+b1 amd64 generic Apache request library - Apache module > ii libapache2-mod-perl2 2.0.9~1624218-2+deb8u1 amd64 Integration of perl with the Apache2 web server > ii libapache2-reload-perl 0.12-3 all module for reloading Perl modules when changed on disk > ii libapache2-request-perl 2.13-4+b1 amd64 generic Apache request library - Perl modules > I don't see above any signifiant difference in configuration between the servers, apart from the fact that the "faulty" server runs a 64-bit version of perl. But I still wonder if this is the issue : http://perldoc.perl.org/functions/srand.html says : "If srand() is not called explicitly, it is called implicitly without a parameter at the first use of the rand operator. However, there are a few situations where programs are likely to want to call srand. One is for generating predictable results, generally for testing or debugging. There, you use srand($seed), with the same $seed each time. Another case is that you may want to call srand() after a fork() to avoid child processes sharing the same seed value as the parent (and consequently each other)." This would tend to imply that the "real" seed used initially by srand() (such as when it is called implicitly at the first call to rand()), is something inside the perl interpreter itself. In a pre-fork configuration, the main Apache process starts first, and loads a perl interpreter. Then this main Apache process is forked into nn Apache children processes. Which means that the initial copies of the perl interpreter, in each child, are also identical. The main Apache process never runs any request (it just passes them to a child, which does run the request), so its copy of the perl interpreter remains "pristine", as it was before the first fork. If at some point there are not enough children alive, the main process forks again to create a new child. So basically all children, present and future, start with the same perl. And thus with the same whatever-it-is that is the seed of the first srand() (implicitly called by the first rand()). So, unless they all do explicitly call srand() once with each a different seed, each child does generate exactly the same sequence of responses to successive rand() calls. In other words, on any given machine, the Nth un-keyed request hitting one particular Apache child, will generate the same key as the Nth un-keyed request hitting any other child (assuming rand() is not used anywhere else). (By "un-keyed request", I mean one which triggers the key-generating instruction). (and N including perhaps also the requests which trigger similar calls to rand to generate a cookie, if they call rand() the same number of times (32)). Except that.. The machine where the problem shows up so quickly, is running a 64-bit perl, while the others are running 32-bit perls. Now I also found this : http://rabexc.org/posts/randomizing-should-be-easy-right-oh I am not sure that I really understand this all the way down, but would this not be a suspect in a case where the behaviour seems different between one 64-bit machine, and a bunch of 32-bit ones ? This being said, it still looks to me as if the current code is flawed on *all* machines, and *will* repeat keys quite often. It just depends again on the exact sequence of requests hitting a specific Apache, and the other parameters I mentioned before. I still believe that the fact that it does not *seem* to happen, is just due to the inherent randomness of these other factors on the production machines.