Bug 57321

Summary: CGI.pm in 4.x base system has a cross-site scripting vulneravility
Product: Base System Reporter: IIJIMA Hiromitsu <delmonta>
Component: binAssignee: Mark Murray <markm>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.7-RELEASE   
Hardware: Any   
OS: Any   

Description IIJIMA Hiromitsu 2003-09-28 17:30:16 UTC
	A cross-site scripting vulnerability is reported in CGI.pm.
	All of the following are affected:
		- 4.x base system's perl 5.005_03
		- ports/japanese/perl5 (5.005_03 with Japanese patch)
		- ports/lang/perl5 (5.6.1)
		- ports/lang/perl5.8 (5.8.0)

	I'll send separate PRs for japanese/perl5 and lang/perl5*.

Fix: 

Replace CGI.pm with the latest version from CPAN,
	or install ports/www/p5-CGI.pm.
How-To-Repeat: 	See the exploit code at:
	http://marc.theaimsgroup.com/?l=bugtraq&m=105880349328877&w=2
Comment 1 IIJIMA Hiromitsu 2003-09-28 17:49:33 UTC
Labelled as CAN-2003-0615 and more information is available at:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0615
Comment 2 matusita freebsd_committer freebsd_triage 2003-09-30 07:07:44 UTC
Responsible Changed
From-To: freebsd-bugs->so

Assigned to the security officer since it is a base-system security problem. 
See also bin/57315 that reports Safe.pm vulnerability.
Comment 3 IIJIMA Hiromitsu 2003-09-30 10:10:48 UTC
In ports/lang/perl5* (perl versions 5.6.1 and 5.8.0), this issue was solved.
Please see latest ports/lang/perl5*/files/patch/patch-CGI.pm and PR ports/57391.
Comment 4 IIJIMA Hiromitsu 2003-10-01 17:12:55 UTC
** POSTING TO PR ports/57390 TOO **

1.
It seems perl 5.005_03 is not affected on all circumstances I have access to,
but it might still be affected on other situations.

When we give the URL like:
        http://host/xss.cgi?">some%20text<!--%20

the original code 
>  $action = $action ? qq/ACTION="$action"/ : $method eq 'GET' ?
>     'ACTION="'.$self->script_name.'"' : '';
uses script_name() subroutine, which returns only '/xss.cgi', not the complete
URL '/xss.cgi?">some%20text<!--%20', at least when used with Apache 1.3.28.

(i.e. Perl 5.6+ and latest ports/www/p5-CGI.pm use complete URL for generating
 ACTION= part, but perl 5.005_03's original CGI.pm does not.)

So the original code's output in this case is
   <FORM METHOD="POST" ACTION="/xss.cgi" (snip)>
and therefore this exploit code does not work.

But I don't know either
  - how other web servers are implemented
  - whether we have a way to give malformed script_name to CGI.pm
    with such servers.

Therefore, the only thing I can tell is that it is unsafe to assume that
script_name()'s return value never contains '"', '>', or '<' characters.


2.
I prepared two patches. Please apply one of them.

The first patch is how tobez fixed this problem at ports/lang/perl{5,5.8}.
This is a patch to substitute the affected code by CGI.pm 3.00's one.

--- CGI.pm.orig Wed Sep 17 09:07:05 2003
+++ CGI.pm      Wed Oct  1 23:40:10 2003
@@ -1413,8 +1413,13 @@

     $method = $method || 'POST';
     $enctype = $enctype || &URL_ENCODED;
-    $action = $action ? qq/ACTION="$action"/ : $method eq 'GET' ?
-       'ACTION="'.$self->script_name.'"' : '';
+    unless (defined $action) {
+       $action = $self->escapeHTML($self->url(-absolute=>1,-path=>1));
+       if (length($ENV{QUERY_STRING})>0) {
+           $action .= "?".$self->escapeHTML($ENV{QUERY_STRING},1);
+       }
+    }
+    $action = qq(action="$action");
     my($other) = @other ? " @other" : '';
     $self->{'.parametersToAdd'}={};
     return qq/<FORM METHOD="$method" $action ENCTYPE="$enctype"$other>\n/;

Applying the patch above will change the behavior of start_form() to use
complete URL rather than script name only, so if you don't want to change it,
please apply the second patch below.

--- CGI.pm.orig Wed Sep 17 09:07:05 2003
+++ CGI.pm      Thu Oct  2 00:46:52 2003
@@ -1414,7 +1414,7 @@
     $method = $method || 'POST';
     $enctype = $enctype || &URL_ENCODED;
     $action = $action ? qq/ACTION="$action"/ : $method eq 'GET' ?
-       'ACTION="'.$self->script_name.'"' : '';
+       'ACTION="'.$self->escapeHTML($self->script_name).'"' : '';
     my($other) = @other ? " @other" : '';
     $self->{'.parametersToAdd'}={};
     return qq/<FORM METHOD="$method" $action ENCTYPE="$enctype"$other>\n/;
Comment 5 matusita freebsd_committer freebsd_triage 2003-10-02 14:04:30 UTC
Responsible Changed
From-To: so->markm

Nectar says that it should be assigned to the FreeBSD 4.x perl maintainer. 
Markm, would you please take care of this PR?  (I believe that you're 
still the maintainer of perl on the FreeBSD base system.)
Comment 6 IIJIMA Hiromitsu 2003-10-03 08:37:55 UTC
The second patch seems incomplete, since the patch leaves qq/ACTION="$action"
part as is.

Mr. Shigeyuki Fukushima, the ports/japanese/perl5 maintainer, suggested me
the above thing while we are discussing the same problem in japanese/perl5
(see PR ports/57390). And he says escape() is better than escapeHTML().

The suggestion (in Japanese) is at:
http://home.jp.FreeBSD.org/cgi-bin/showmail/ports-jp/14200

Therefore, the revised version of the second patch is:

--- CGI.pm.orig Wed Sep 17 09:07:05 2003
+++ CGI.pm      Thu Oct  2 00:46:52 2003
@@ -1414,7 +1414,7 @@
     $method = $method || 'POST';
     $enctype = $enctype || &URL_ENCODED;
-    $action = $action ? qq/ACTION="$action"/ : $method eq 'GET' ?
-       'ACTION="'.$self->script_name.'"' : '';
+    $action = $action ? 'ACTION="'.$self->escape($action).'"' : $method eq 'GET' ?
+       'ACTION="'.$self->escape($self->script_name).'"' : '';
     my($other) = @other ? " @other" : '';
     $self->{'.parametersToAdd'}={};
     return qq/<FORM METHOD="$method" $action ENCTYPE="$enctype"$other>\n/;
Comment 7 IIJIMA Hiromitsu 2003-10-03 14:19:11 UTC
> Mr. Shigeyuki Fukushima
...
> says escape() is better than escapeHTML().

Using escape() is not appropriate, since it escapes even '/'. For example,
if we make a call like $cgi->start_form(-action=>'/~username/foo.cgi'),
escape() results in '%2F%7Eusername%2Ffoo.cgi', which will not works work
on most web servers.

New patch.

--- CGI.pm.orig Wed Sep 17 09:07:05 2003
+++ CGI.pm      Thu Oct  2 00:46:52 2003
@@ -1414,7 +1414,7 @@
     $method = $method || 'POST';
     $enctype = $enctype || &URL_ENCODED;
-    $action = $action ? qq/ACTION="$action"/ : $method eq 'GET' ?
-       'ACTION="'.$self->script_name.'"' : '';
+    $action = $action ? 'ACTION="'.$self->escapeHTML($action).'"' : $method eq 'GET' ?
+       'ACTION="'.$self->escapeHTML($self->script_name).'"' : '';
     my($other) = @other ? " @other" : '';
     $self->{'.parametersToAdd'}={};
     return qq/<FORM METHOD="$method" $action ENCTYPE="$enctype"$other>\n/;
Comment 8 IIJIMA Hiromitsu 2003-10-03 19:03:33 UTC
PR ports/57390 (japanese/perl5 counterpart of this problem) was closed with
my last patch (Fri, 03 Oct 2003 22:19:11 +0900 one).
Comment 9 Mark Murray freebsd_committer freebsd_triage 2005-03-28 13:47:03 UTC
State Changed
From-To: open->closed

CGI.pm in the base tree is off-the-beaten-track. If this really 
is a threat, I'd recommend removing it, but the code is deprecated 
anyway.