Make sure we do not pass multiple CGI parameters in function calls
authorSimon McVittie <smcv@debian.org>
Sat, 11 Oct 2014 08:28:22 +0000 (09:28 +0100)
committerSimon McVittie <smcv@debian.org>
Thu, 16 Oct 2014 21:24:47 +0000 (22:24 +0100)
When CGI->param is called in list context, such as in function
parameters, it expands to all the potentially multiple values
of the parameter: for instance, if we parse query string a=b&a=c&d=e
and call func($cgi->param('a')), that's equivalent to func('b', 'c').
Most of the functions we're calling do not expect that.

I do not believe this is an exploitable security vulnerability in
ikiwiki, but it was exploitable in Bugzilla.

IkiWiki/Plugin/attachment.pm
IkiWiki/Plugin/goto.pm
IkiWiki/Plugin/inline.pm
IkiWiki/Plugin/openid.pm
IkiWiki/Plugin/poll.pm
IkiWiki/Plugin/rename.pm

index d56dd18ad8ded90e3dd6f46598e7bc632359d4b5..fb8a6539eac53fd66c85e4c98c09bfb1dbf71bb7 100644 (file)
@@ -132,7 +132,7 @@ sub formbuilder (@) {
 
        return if ! defined $form->field("do") || ($form->field("do") ne "edit" && $form->field("do") ne "create") ;
 
 
        return if ! defined $form->field("do") || ($form->field("do") ne "edit" && $form->field("do") ne "create") ;
 
-       my $filename=Encode::decode_utf8($q->param('attachment'));
+       my $filename=Encode::decode_utf8(scalar $q->param('attachment'));
        if (defined $filename && length $filename) {
                attachment_store($filename, $form, $q, $params{session});
        }
        if (defined $filename && length $filename) {
                attachment_store($filename, $form, $q, $params{session});
        }
@@ -142,7 +142,7 @@ sub formbuilder (@) {
        }
 
        if ($form->submitted eq "Insert Links") {
        }
 
        if ($form->submitted eq "Insert Links") {
-               my $page=quotemeta(Encode::decode_utf8($q->param("page")));
+               my $page=quotemeta(Encode::decode_utf8(scalar $q->param("page")));
                my $add="";
                foreach my $f ($q->param("attachment_select")) {
                        $f=Encode::decode_utf8($f);
                my $add="";
                foreach my $f ($q->param("attachment_select")) {
                        $f=Encode::decode_utf8($f);
index 6b596ac8b6af95641dec071071e5be38b3898f87..3a946b19da9a487a5e76b395a709a2629560dff4 100644 (file)
@@ -27,7 +27,7 @@ sub cgi_goto ($;$) {
        my $page = shift;
 
        if (!defined $page) {
        my $page = shift;
 
        if (!defined $page) {
-               $page = IkiWiki::decode_utf8($q->param("page"));
+               $page = IkiWiki::decode_utf8(scalar $q->param("page"));
 
                if (!defined $page) {
                        error("missing page parameter");
 
                if (!defined $page) {
                        error("missing page parameter");
index f578526cc0da9fe1c369c5d1e709fe21f5154341..300941943b298be6142713005ee681f6e55cd8df 100644 (file)
@@ -119,7 +119,7 @@ sub sessioncgi ($$) {
        my $session=shift;
 
        if ($q->param('do') eq 'blog') {
        my $session=shift;
 
        if ($q->param('do') eq 'blog') {
-               my $page=titlepage(decode_utf8($q->param('title')));
+               my $page=titlepage(decode_utf8(scalar $q->param('title')));
                $page=~s/(\/)/"__".ord($1)."__"/eg; # don't create subdirs
                # if the page already exists, munge it to be unique
                my $from=$q->param('from');
                $page=~s/(\/)/"__".ord($1)."__"/eg; # don't create subdirs
                # if the page already exists, munge it to be unique
                my $from=$q->param('from');
index 3b96e4b8e411c5f29afc25b58e15cdfd9f70121d..63112d9836342b3c29b04e046ac7f3fc5aeec48c 100644 (file)
@@ -223,7 +223,7 @@ sub auth ($$) {
        }
        elsif (defined $q->param('openid_identifier')) {
                # myopenid.com affiliate support
        }
        elsif (defined $q->param('openid_identifier')) {
                # myopenid.com affiliate support
-               validate($q, $session, $q->param('openid_identifier'));
+               validate($q, $session, scalar $q->param('openid_identifier'));
        }
 }
 
        }
 }
 
index 3bd4af2060111ed4dbe12e3262c0f1e200ca6ba7..eb0e6ef04d086ad34e900a31f37a2407edbefabc 100644 (file)
@@ -99,7 +99,7 @@ sub sessioncgi ($$) {
        my $cgi=shift;
        my $session=shift;
        if (defined $cgi->param('do') && $cgi->param('do') eq "poll") {
        my $cgi=shift;
        my $session=shift;
        if (defined $cgi->param('do') && $cgi->param('do') eq "poll") {
-               my $choice=decode_utf8($cgi->param('choice'));
+               my $choice=decode_utf8(scalar $cgi->param('choice'));
                if (! defined $choice || not length $choice) {
                        error("no choice specified");
                }
                if (! defined $choice || not length $choice) {
                        error("no choice specified");
                }
index f7ea21b5355aed4942defb8102b1af0088059cc0..6d56340b896519e921e9b6c7d8a06ffd1d56fe2a 100644 (file)
@@ -237,7 +237,7 @@ sub postrename ($$$;$$) {
                # on it.
                $oldcgi->param("editcontent",
                        renamepage_hook($dest, $src, $dest,
                # on it.
                $oldcgi->param("editcontent",
                        renamepage_hook($dest, $src, $dest,
-                                $oldcgi->param("editcontent")));
+                               scalar $oldcgi->param("editcontent")));
 
                # Get a new edit token; old was likely invalidated.
                $oldcgi->param("rcsinfo",
 
                # Get a new edit token; old was likely invalidated.
                $oldcgi->param("rcsinfo",
@@ -297,7 +297,7 @@ sub sessioncgi ($$) {
 
        if ($q->param("do") eq 'rename') {
                my $session=shift;
 
        if ($q->param("do") eq 'rename') {
                my $session=shift;
-               my ($form, $buttons)=rename_form($q, $session, Encode::decode_utf8($q->param("page")));
+               my ($form, $buttons)=rename_form($q, $session, Encode::decode_utf8(scalar $q->param("page")));
                IkiWiki::decode_form_utf8($form);
                my $src=$form->field("page");
 
                IkiWiki::decode_form_utf8($form);
                my $src=$form->field("page");
 
@@ -332,7 +332,7 @@ sub sessioncgi ($$) {
                                IkiWiki::Plugin::attachment::is_held_attachment($src);
                        if ($held) {
                                rename($held, IkiWiki::Plugin::attachment::attachment_holding_location($dest));
                                IkiWiki::Plugin::attachment::is_held_attachment($src);
                        if ($held) {
                                rename($held, IkiWiki::Plugin::attachment::attachment_holding_location($dest));
-                               postrename($q, $session, $src, $dest, $q->param("attachment"))
+                               postrename($q, $session, $src, $dest, scalar $q->param("attachment"))
                                        unless defined $srcfile;
                        }
                        
                                        unless defined $srcfile;
                        }
                        
@@ -438,7 +438,7 @@ sub sessioncgi ($$) {
                                $renamesummary.=$template->output;
                        }
 
                                $renamesummary.=$template->output;
                        }
 
-                       postrename($q, $session, $src, $dest, $q->param("attachment"));
+                       postrename($q, $session, $src, $dest, scalar $q->param("attachment"));
                }
                else {
                        IkiWiki::showform($form, $buttons, $session, $q);
                }
                else {
                        IkiWiki::showform($form, $buttons, $session, $q);