| Summary: | CGI.pm in 4.x base system has a cross-site scripting vulneravility | ||
|---|---|---|---|
| Product: | Base System | Reporter: | IIJIMA Hiromitsu <delmonta> |
| Component: | bin | Assignee: | 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
Labelled as CAN-2003-0615 and more information is available at: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0615 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. 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. ** 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/;
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.) 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/; > 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/; PR ports/57390 (japanese/perl5 counterpart of this problem) was closed with my last patch (Fri, 03 Oct 2003 22:19:11 +0900 one). 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. |