Skip Menu |

This queue is for tickets about the FCGI CPAN distribution.

Report information
The Basics
Id: 68380
Status: resolved
Priority: 0/
Queue: FCGI

People
Owner: Nobody in particular
Requestors: ssinyagin [...] yahoo.com
Cc: dam [...] cpan.org
jquelin [...] cpan.org
AdminCc:

Bug Information
Severity: Critical
Broken in:
  • 0.70
  • 0.71
  • 0.71_01
  • 0.71_02
  • 0.71_03
  • 0.72
  • 0.73
Fixed in: (no value)



Subject: FCGI-0.70 to 0.72 with perl5.12: CGI.pm receives CGI variables from previous requests
hi, I'm using FCGI in Torrus, here's the code: http://goo.gl/Gr0oW http://goo.gl/uYBN5 I installed perl 5.12.3 from sources, and also the latest FCGI.pm. CGI.pm version: 3.49 The problem is reproducible in FCGI-0.70 , 0.71, 0.72. Problem: often CGI.pm receives CGI variables from previous requests, and $q->url(-path => 1) shows a request which was executed before. The problem is visible when more than one FastCGI processes are launched. With only one FastCGI handler, the problem is not seen. The server runs Apache with mod_fastcgi (Ubuntu package: libapache2-mod-fastcgi 2.4.6-1). Downgrading to FCGI-0.69 has solved the problem, although perl is complaining about defined(%hash) statements.
I reproduced the same problem on a Redhat server with Apache+mod_fcgid
Is it reproducible with a mimimal script such as: #!/usr/bin/perl use strict; use warnings; use CGI::Fast; while (my $q = CGI::Fast->new) { print $q->header(-type => 'text/plain'), $q->url(-path => 1), "\n"; } Could you also try with the latest CGI.pm version? Output of perl -V might prove helpful also. -- chansen
Strange, chansen, I can't reproduce it with this little script -- it prints the URL as expected
For some reason the global hash was not working as expected. This patch replaces it with a global hashref. Tests show behavior as expected: diff --git a/perl/FCGI.PL b/perl/FCGI.PL index 746aaf3..ce0d70b 100644 --- a/perl/FCGI.PL +++ b/perl/FCGI.PL @@ -295,14 +295,14 @@ sub Request(;***$*$) { sub accept() { warn "accept called as a method; you probably wanted to call Accept" if @_; - if (%FCGI::ENV) { - %ENV = %FCGI::ENV; + if (defined $FCGI::ENV) { + %ENV = %$FCGI::ENV; } else { - %FCGI::ENV = %ENV; + $FCGI::ENV = {%ENV}; } my $rc = Accept($global_request); - for (keys %FCGI::ENV) { - $ENV{$_} = $FCGI::ENV{$_} unless exists $ENV{$_}; + for (keys %$FCGI::ENV) { + $ENV{$_} = $FCGI::ENV->{$_} unless exists $ENV{$_}; } # not SFIO @@ -314,7 +314,7 @@ sub accept() { sub finish() { warn "finish called as a method; you probably wanted to call Finish" if @_; - %ENV = %FCGI::ENV if %FCGI::ENV; + %ENV = %$FCGI::ENV if (defined $FCGI::ENV); # not SFIO if (tied (*STDIN)) {
I'm a bit confused, first you said you couldn't reproduce the issue with the script i sent, then later you said "For some reason the global hash was not working as expected.". We need a reproducible case before we can accept any patches for this issue. -- chansen
Subject: Re: [rt.cpan.org #68380] FCGI-0.70 to 0.72 with perl5.12: CGI.pm receives CGI variables from previous requests
Date: Wed, 25 May 2011 10:05:16 -0700 (PDT)
To: "bug-FCGI [...] rt.cpan.org" <bug-FCGI [...] rt.cpan.org>
From: Stanislav Sinyagin <ssinyagin [...] yahoo.com>
I could not reproduce it with a small script like yours, but it was reproducible in my Torrus installation. FCGI performs some manipulations with environment variables which are not quite clear to me, so I can't really analyze what's going on in it. In the FCGI Git repository (git://git.shadowcat.co.uk/catagits/fcgi2.git) the commit that breaks the functionality is 03e35f7.
We have been unsuccessful with reproducing your reported issue, using persistent and non- persistent connections. Unless a minimal test-case is provided this report will be rejected. -- chansen
Subject: Re: [rt.cpan.org #68380] FCGI-0.70 to 0.72 with perl5.12: CGI.pm receives CGI variables from previous requests
Date: Tue, 31 May 2011 01:30:58 -0700 (PDT)
To: "bug-FCGI [...] rt.cpan.org" <bug-FCGI [...] rt.cpan.org>
From: Stanislav Sinyagin <ssinyagin [...] yahoo.com>
well, a full Torrus installation would be a bit too much effort. I'll try to produce a test case within few days. Show quoted text
>
I managed to reproduce it. test script: ============ #!/opt/nmstools/thirdparty/bin/perl use lib '/opt/nmstools/src/tmp/fcgi2/perl/blib/lib'; use lib '/opt/nmstools/src/tmp/fcgi2/perl/blib/arch'; use strict; use warnings; use CGI::Fast; while (my $q = new CGI::Fast) { print $q->header(-type => 'text/plain'); print $FCGI::VERSION, "\n", $q->param('a'), "\n", $q->url(-path => 1), "\n"; } ================== Apache configuration: ========= AddHandler fcgid-script .fcgi ScriptAlias /torrus/xxx "/opt/nmstools/src/tmp/fcgitest.fcgi" <Location /torrus> Order Allow,Deny Allow from all Options +ExecCGI </Location> ========= First, I access the following URL, and the printed output is as expected: http://HOST/torrus/xxx/ff?a=ddd Then I access the following URL: http://HOST/torrus/xxx and the script prints: ========== 0.73 http://HOST/torrus/xxx/ff ========== Expected result would be the "http://HOST/torrus/xxx". Attached, see the patch against 0.73 without any broken linebreaks. It solves the problem, but it's still not completely clear how the logic behind %ENV manipulation works in FCGI.pm cheers, stanislav
Subject: FCGI-0.73-ssinyagin-20110605.patch
diff --git a/perl/FCGI.PL b/perl/FCGI.PL index 746aaf3..ce0d70b 100644 --- a/perl/FCGI.PL +++ b/perl/FCGI.PL @@ -295,14 +295,14 @@ sub Request(;***$*$) { sub accept() { warn "accept called as a method; you probably wanted to call Accept" if @_; - if (%FCGI::ENV) { - %ENV = %FCGI::ENV; + if (defined $FCGI::ENV) { + %ENV = %$FCGI::ENV; } else { - %FCGI::ENV = %ENV; + $FCGI::ENV = {%ENV}; } my $rc = Accept($global_request); - for (keys %FCGI::ENV) { - $ENV{$_} = $FCGI::ENV{$_} unless exists $ENV{$_}; + for (keys %$FCGI::ENV) { + $ENV{$_} = $FCGI::ENV->{$_} unless exists $ENV{$_}; } # not SFIO @@ -314,7 +314,7 @@ sub accept() { sub finish() { warn "finish called as a method; you probably wanted to call Finish" if @_; - %ENV = %FCGI::ENV if %FCGI::ENV; + %ENV = %$FCGI::ENV if (defined $FCGI::ENV); # not SFIO if (tied (*STDIN)) {
There is quite good analysis in the Debian bug report about the same issue, http://bugs.debian.org/607479 -- dam
For the record, this is CVE-2011-2766.
This isn't really an issue within FCGI package, the API CGI::Fast is using was deprecated 2000- 04-09 with the commit <http://git.shadowcat.co.uk/gitweb/gitweb.cgi? p=catagits/fcgi2.git;a=commit;f=perl/oldinterface.pod;h=d2900ee847a5f541f30ca6cd47cc07a Show quoted text
2833a7f4a>.
We recognize the usage of CGI::Fast package and will merge the proposed fix and notify the CGI.pm developers that they are using a deprecated API. -- chansen
Patch has been applied [1] and a new release has been released on CPAN [2]. [1] <http://git.shadowcat.co.uk/gitweb/gitweb.cgi? p=catagits/fcgi2.git;a=commitdiff;h=297693dc8362d25bb25e473899c72508a0f71d2e> [2] http://search.cpan.org/dist/FCGI/ -- chansen