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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.