On Fri, Mar 15, 2019 at 02:25:35PM +0100, Peter J. Philipp wrote:
> I have have created a patch for cvsweb port that needs review and help in 
> getting it into the port itself.  I'd like to apologize to Marc Espie for
> contacting him regarding this port based on his last check-in on this port,  
> and thanks to Stuart Henderson for directing me here.
> 
> The patch changed since my last submission to misc@ and since I am a complete
> newbie in perl this would need a pro to look at it whether it's correct.
>
> I have produced the patch with 'diff -u cvsweb.orig cvsweb' directly in the
> /var/www/cgi-bin directory.  Credit goes to Ezio Paglia for finding this XSS
> vuln.  Also the cvsweb at openbsd.org is affected and can be checked with:

I looked this over and updated the patch to be against the port.  It
seems to be good and I only found a couple other places that needed to
be escaped, the "stickyvars" section and the tr1/tr2 inputs in doLog,
although r1, r2, tr1 and tr2 are part of "unsafevars" so their content
is pretty limited already.

It was a pretty quick look so I don't doubt that there are more, and I
didn't actually get a chance to test it out, so hopefully someone else
can.

> https://cvsweb.openbsd.org/src/sbin/clri/clri.c?f=%22%3E%3Cscript%3Ealert(%27XSS%27)%3C/script%3E
> 
> in chrome the XSS check activates immediately, I don't know what firefox does.

With NoScript it throws up a big error saying there was an attempted
XSS, without NoScript it throws up an alert box saying "XSS".
Index: Makefile
===================================================================
RCS file: /cvs/ports/devel/cvsweb/Makefile,v
retrieving revision 1.60
diff -u -p -r1.60 Makefile
--- Makefile    4 Sep 2018 12:46:10 -0000       1.60
+++ Makefile    16 Mar 2019 00:17:58 -0000
@@ -3,7 +3,7 @@
 COMMENT=       CGI script to browse CVS repository trees
 
 DISTNAME=      cvsweb-2.0.6
-REVISION=      26
+REVISION=      27
 CATEGORIES=    devel www
 HOMEPAGE=      http://www.freebsd.org/projects/cvsweb.html
 
Index: patches/patch-cvsweb_cgi
===================================================================
RCS file: /cvs/ports/devel/cvsweb/patches/patch-cvsweb_cgi,v
retrieving revision 1.13
diff -u -p -r1.13 patch-cvsweb_cgi
--- patches/patch-cvsweb_cgi    7 Apr 2013 20:07:24 -0000       1.13
+++ patches/patch-cvsweb_cgi    16 Mar 2019 00:17:58 -0000
@@ -1,6 +1,7 @@
 $OpenBSD: patch-cvsweb_cgi,v 1.13 2013/04/07 20:07:24 naddy Exp $
---- cvsweb.cgi.orig    Thu Sep 26 22:56:05 2002
-+++ cvsweb.cgi Sun Apr  7 14:15:55 2013
+Index: cvsweb.cgi
+--- cvsweb.cgi.orig
++++ cvsweb.cgi
 @@ -1,4 +1,4 @@
 -#!/usr/bin/perl -wT
 +#!/usr/bin/perl -w
@@ -37,7 +38,18 @@ $OpenBSD: patch-cvsweb_cgi,v 1.13 2013/0
  );
  
  @LOGSORTKEYS = qw(cvs date rev);
-@@ -2014,20 +2009,6 @@ sub doDiff($$$$$$) {
+@@ -1003,8 +998,9 @@ if (-d $fullname) {
+       if (scalar %tags || $input{only_with_tag}) {
+               print "<form method=\"get\" action=\"./\">\n";
+               foreach my $var (@stickyvars) {
++                      my $tmpvar = htmlquote($input{$var});
+                       print
+-                          "<input type=\"hidden\" name=\"$var\" 
value=\"$input{$var}\">\n"
++                          "<input type=\"hidden\" name=\"$var\" 
value=\"$tmpvar\">\n"
+                           if (defined($input{$var})
+                           && (!defined($DEFAULTVALUE{$var})
+                           || $input{$var} ne $DEFAULTVALUE{$var})
+@@ -2014,20 +2010,6 @@ sub doDiff($$$$$$) {
        my @difftype       = @{$difftype->{'opts'}};
        my $human_readable = $difftype->{'colored'};
  
@@ -58,7 +70,25 @@ $OpenBSD: patch-cvsweb_cgi,v 1.13 2013/0
        if ($human_readable) {
                if ($hr_ignwhite) {
                        push @difftype, '-w';
-@@ -2658,7 +2639,7 @@ sub printLog($;$) {
+@@ -2631,7 +2613,7 @@ sub printLog($;$) {
+                               sprintf(
+                                       '%s/%s?annotate=%s%s', $scriptname,
+                                       urlencode($where),     $_,
+-                                      $barequery
++                                      htmlquote($barequery)
+                               )
+                       );
+               }
+@@ -2644,7 +2626,7 @@ sub printLog($;$) {
+                                       '[select for diffs]',
+                                       sprintf(
+                                               '%s?r1=%s%s', $scriptwhere,
+-                                              $_,           $barequery
++                                              $_,           
htmlquote($barequery)
+                                       )
+                               );
+                       } else {
+@@ -2658,7 +2640,7 @@ sub printLog($;$) {
        if (/^1\.1\.1\.\d+$/) {
                print " <i>(vendor branch)</i>";
        }
@@ -67,3 +97,57 @@ $OpenBSD: patch-cvsweb_cgi,v 1.13 2013/0
                my ($est) = $mytz[(localtime($date{$_}))[8]];
                print ", <i>", scalar localtime($date{$_}), " $est</i> (";
        } else {
+@@ -2847,7 +2829,7 @@ sub doLog($) {
+ 
+       foreach (@stickyvars) {
+               printf('<input type="hidden" name="%s" value="%s">', $_,
+-                  $input{$_})
++                  htmlquote($input{$_}))
+                   if (defined($input{$_})
+                   && ((!defined($DEFAULTVALUE{$_})
+                   || $input{$_} ne $DEFAULTVALUE{$_}) && $input{$_} ne ""));
+@@ -2860,7 +2842,7 @@ sub doLog($) {
+       print $sel;
+       print "</select>\n";
+       $diffrev = $revdisplayorder[$#revdisplayorder];
+-      $diffrev = $input{"r1"} if (defined($input{"r1"}));
++      $diffrev = htmlquote($input{"r1"}) if (defined($input{"r1"}));
+       print
+           "<input type=\"text\" size=\"$inputTextSize\" name=\"tr1\" 
value=\"$diffrev\" onchange=\"this.form.r1.selectedIndex=0\"></td>\n";
+       print "<td><br></td>\n</tr>\n";
+@@ -2871,7 +2853,7 @@ sub doLog($) {
+       print $sel;
+       print "</select>\n";
+       $diffrev = $revdisplayorder[0];
+-      $diffrev = $input{"r2"} if (defined($input{"r2"}));
++      $diffrev = htmlquote($input{"r2"}) if (defined($input{"r2"}));
+       print
+           "<input type=\"text\" size=\"$inputTextSize\" name=\"tr2\" 
value=\"$diffrev\" onchange=\"this.form.r2.selectedIndex=0\"></td>\n";
+       print "<td><input type=\"submit\" value=\"  Get Diffs  \" 
accesskey=\"G\"></td>\n";
+@@ -2916,7 +2898,8 @@ sub doLog($) {
+               next if ($_ eq "f");
+               next if ($_ eq "only_with_tag");
+               next if ($_ eq "logsort");
+-              print "<input type=\"hidden\" name=\"$_\" 
value=\"$input{$_}\">\n"
++              printf "<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
++                      $_, htmlquote($input{$_})
+                   if (defined($input{$_})
+                   && (!defined($DEFAULTVALUE{$_})
+                   || $input{$_} ne $DEFAULTVALUE{$_}) && $input{$_} ne "");
+@@ -3286,7 +3269,7 @@ sub clickablePath($$) {
+                                       join ('', $scriptname,
+                                       urlencode($wherepath),
+                                       (!$last || $lastslash ? '/' : ''),
+-                                      $query,
++                                      htmlquote($query),
+                                       (!$last || $lastslash ? "#dirlist" : "")
+                               ));
+                       } else {    # do not make a link to the current dir
+@@ -3527,6 +3510,7 @@ sub htmlquote($) {
+       # Special Characters; RFC 1866
+       s/&/&amp;/g;
+       s/\"/&quot;/g;
++      s/%22/&quot;/g;
+       s/</&lt;/g;
+       s/>/&gt;/g;
+ 

Reply via email to