]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 192677: Add new test to flag failure-to-filter situations in the templates, and...
authorjustdave%syndicomm.com <>
Fri, 25 Apr 2003 03:45:08 +0000 (03:45 +0000)
committerjustdave%syndicomm.com <>
Fri, 25 Apr 2003 03:45:08 +0000 (03:45 +0000)
Filter patch by Gervase Markham <gerv@mozilla.org>
Template patches by Gervase Markham <gerv@mozilla.org> and Dave Miller <justdave@netscape.com>
r= gerv, bbaetz, justdave
a= justdave

15 files changed:
duplicates.cgi
t/008filter.t [new file with mode: 0644]
template/en/default/attachment/edit.html.tmpl
template/en/default/bug/create/create.html.tmpl
template/en/default/bug/create/make-template.html.tmpl
template/en/default/bug/show-multiple.html.tmpl
template/en/default/filterexceptions.pl [new file with mode: 0644]
template/en/default/global/choose-product.html.tmpl
template/en/default/global/code-error.html.tmpl
template/en/default/global/hidden-fields.html.tmpl
template/en/default/global/message.html.tmpl
template/en/default/list/change-columns.html.tmpl
template/en/default/list/list.html.tmpl
template/en/default/list/table.html.tmpl
template/en/default/reports/duplicates.html.tmpl

index 50affa6df8d25966d8aca3269af3f4c7f7839c30..7172fa6f9974cdf4aba01f182baaa4454de08408 100755 (executable)
@@ -57,7 +57,7 @@ my $sortby = formvalue("sortby");
 my $changedsince = formvalue("changedsince", 7);
 my $maxrows = formvalue("maxrows", 100);
 my $openonly = formvalue("openonly");
-my $reverse = formvalue("reverse");
+my $reverse = formvalue("reverse") ? 1 : 0;
 my $product = formvalue("product");
 my $sortvisible = formvalue("sortvisible");
 my @buglist = (split(/[:,]/, formvalue("bug_id")));
@@ -147,6 +147,18 @@ my $generic_query = "
 # Limit to a single product if requested             
 $generic_query .= (" product = " . SqlQuote($product) . " AND ") if $product;
  
+my $origmaxrows = $maxrows;
+detaint_natural($maxrows)
+  || ThrowUserError("The maximum number of rows, '" . html_quote($origmaxrows) .
+                    "', must be a positive integer.",
+                    "Invalid Max Rows");
+
+my $origchangedsince = $changedsince;
+detaint_natural($changedsince)
+  || ThrowUserError("The 'changed since' value, '" . html_quote($origchangedsince) .
+                    "', must be an integer >= 0.",
+                    "Invalid Changed Since");
+
 my @bugs;
 my @bug_ids; 
 my $loop = 0;
diff --git a/t/008filter.t b/t/008filter.t
new file mode 100644 (file)
index 0000000..10d7fc6
--- /dev/null
@@ -0,0 +1,182 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code are the Bugzilla tests.
+#
+# The Initial Developer of the Original Code is Jacob Steenhagen.
+# Portions created by Jacob Steenhagen are
+# Copyright (C) 2001 Jacob Steenhagen. All
+# Rights Reserved.
+#
+# Contributor(s): Gervase Markham <gerv@gerv.net>
+
+#################
+#Bugzilla Test 8#
+#####filter######
+
+# This test scans all our templates for every directive. Having eliminated
+# those which cannot possibly cause XSS problems, it then checks the rest
+# against the safe list stored in the filterexceptions.pl file. 
+
+# Sample exploit code: '>"><script>alert('Oh dear...')</script>
+
+use strict;
+use lib 't';
+
+use vars qw(%safe);
+
+use Support::Templates;
+use File::Spec 0.82;
+use Test::More tests => $Support::Templates::num_actual_files;
+use Cwd;
+
+# Undefine the record separator so we can read in whole files at once
+my $oldrecsep = $/;
+$/ = undef;
+my $topdir = cwd;
+
+foreach my $path (@Support::Templates::include_paths) {
+    $path =~ m|template/([^/]+)/|;
+    my $lang = $1;
+    chdir $topdir; # absolute path
+    my @testitems = Support::Templates::find_actual_files($path);
+    
+    next unless @testitems;
+    
+    # Some people require this, others don't. No-one knows why.
+    chdir $path; # relative path
+    
+    # We load a %safe list of acceptable exceptions.
+    if (!-r "filterexceptions.pl") {
+        ok(0, "$path has templates but no filterexceptions.pl file. --ERROR");
+        next;
+    }
+    else {
+        do "filterexceptions.pl";
+    }
+    
+    # We preprocess the %safe hash of lists into a hash of hashes. This allows
+    # us to flag which members were not found, and report that as a warning, 
+    # thereby keeping the lists clean.
+    foreach my $file (keys %safe) {
+        my $list = $safe{$file};
+        $safe{$file} = {};
+        foreach my $directive (@$list) {
+            $safe{$file}{$directive} = 0;    
+        }
+    }
+
+    foreach my $file (@testitems) {
+        # There are some files we don't check, because there is no need to
+        # filter their contents due to their content-type.
+        if ($file =~ /\.(txt|png)\.tmpl$/) {
+            ok(1, "($lang) $file is filter-safe");
+            next;
+        }
+        
+        # Read the entire file into a string
+        open (FILE, "<$file") || die "Can't open $file: $!\n";    
+        my $slurp = <FILE>;
+        close (FILE);
+
+        my @unfiltered;
+
+        # /g means we execute this loop for every match
+        # /s means we ignore linefeeds in the regexp matches
+        while ($slurp =~ /\[%(.*?)%\]/gs) {
+            my $directive = $1;
+
+            my @lineno = ($` =~ m/\n/gs);
+            my $lineno = scalar(@lineno) + 1;
+
+            # Comments
+            next if $directive =~ /^[+-]?#/;        
+
+            # Remove any leading/trailing + or - and whitespace.
+            $directive =~ s/^[+-]?\s*//;
+            $directive =~ s/\s*[+-]?$//;
+
+            # Directives
+            next if $directive =~ /^(IF|END|UNLESS|FOREACH|PROCESS|INCLUDE|
+                                     BLOCK|USE|ELSE|NEXT|LAST|DEFAULT|FLUSH|
+                                     ELSIF|SET|SWITCH|CASE)/x;
+
+            # Simple assignments
+            next if $directive =~ /^[\w\.\$]+\s+=\s+/;
+
+            # Conditional literals with either sort of quotes 
+            # There must be no $ in the string for it to be a literal
+            next if $directive =~ /^(["'])[^\$]*[^\\]\1/;
+
+            # Special values always used for numbers
+            next if $directive =~ /^[ijkn]$/;
+            next if $directive =~ /^count$/;
+            
+            # Params
+            next if $directive =~ /^Param\(/;
+
+            # Other functions guaranteed to return OK output
+            next if $directive =~ /^(time2str|GetBugLink)\(/;
+
+            # Safe Template Toolkit virtual methods
+            next if $directive =~ /\.(size)$/;
+
+            # Special Template Toolkit loop variable
+            next if $directive =~ /^loop\.(index|count)$/;
+            
+            # Things which are already filtered
+            # Note: If a single directive prints two things, and only one is 
+            # filtered, we may not catch that case.
+            next if $directive =~ /FILTER\ (html|csv|js|url_quote|quoteUrls|
+                                            time|uri|xml)/x;
+
+            # Exclude those on the nofilter list
+            if (defined($safe{$file}{$directive})) {
+                $safe{$file}{$directive}++;
+                next;
+            };
+
+            # This intentionally makes no effort to eliminate duplicates; to do
+            # so would merely make it more likely that the user would not 
+            # escape all instances when attempting to correct an error.
+            push(@unfiltered, "$lineno:$directive");
+        }  
+
+        my $fullpath = File::Spec->catfile($path, $file);
+        
+        if (@unfiltered) {
+            my $uflist = join("\n  ", @unfiltered);
+            ok(0, "($lang) $fullpath has unfiltered directives:\n  $uflist\n--ERROR");
+        }
+        else {
+            # Find any members of the exclusion list which were not found
+            my @notfound;
+            foreach my $directive (keys %{$safe{$file}}) {
+                push(@notfound, $directive) if ($safe{$file}{$directive} == 0);    
+            }
+
+            if (@notfound) {
+                my $nflist = join("\n  ", @notfound);
+                ok(0, "($lang) $fullpath - FEL has extra members:\n  $nflist\n" . 
+                                                                  "--WARNING");
+            }
+            else {
+                # Don't use the full path here - it's too long and unwieldy.
+                ok(1, "($lang) $file is filter-safe");
+            }
+        }
+    }
+}
+
+$/ = $oldrecsep;
+
+exit 0;
index 873f73b59eedf0fb97f14121520ffb80f503b40e..8c4eae569cfbe4971ffad28733b4ffec179a0a87 100644 (file)
@@ -50,7 +50,7 @@
       // If this is a plaintext document, remove cruft that Mozilla adds
       // because it treats it as an HTML document with a big PRE section.
       // http://bugzilla.mozilla.org/show_bug.cgi?id=86012
-      var contentType = '[% contenttype %]';
+      var contentType = '[% contenttype FILTER js %]';
       if ( contentType == 'text/plain' )
         {
           theContent = theContent.replace( /^<html><head\/><body><pre>/i , "" );
index 259f2ea8e1d51d8bd4b1b8341521c003bbd8fe38..9afd5b2774916d59658149ecf4bd477eea68fb24 100644 (file)
     [% sel = { description => 'Priority', name => 'priority' } %]
     [% INCLUDE select %]
   [% ELSE %]
-    <input type="hidden" name="priority" value="[% default.priority %]">
+    <input type="hidden" name="priority" 
+           value="[% default.priority FILTER html %]">
   [% END %]
 
   [% sel = { description => 'Severity', name => 'bug_severity' } %]
index 1e2495ff86fbd1d2f91ca8a5452862654a2497e5..958d183cc9840b14e4aa11b1b31c86d6a3b77c02 100644 (file)
@@ -25,7 +25,7 @@
 %]
 
 <p>
-If you bookmark <a href="enter_bug.cgi?[% url %]">this link</a>,
+If you bookmark <a href="enter_bug.cgi?[% url FILTER html %]">this link</a>,
 going to the bookmark will bring up the enter bug page with the fields
 initialized as you've requested.
 </p>
index 0e73f4ad72cc272aa981915f64a2cd7460cbddf3..60d23ce059e6a4831382583a362abccc0e1f7bb6 100644 (file)
     <tr>
       <td colspan="4">
         <b>URL:</b>&nbsp;
-        <a href="[% bug.bug_file_loc %]">[% bug.bug_file_loc FILTER html %]</a> 
+        <a href="[% bug.bug_file_loc FILTER html %]">
+                 [% bug.bug_file_loc FILTER html %]</a> 
     </tr>
     
     <tr>
diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl
new file mode 100644 (file)
index 0000000..08a021b
--- /dev/null
@@ -0,0 +1,407 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code are the Bugzilla tests.
+#
+# The Initial Developer of the Original Code is Jacob Steenhagen.
+# Portions created by Jacob Steenhagen are
+# Copyright (C) 2001 Jacob Steenhagen. All
+# Rights Reserved.
+#
+# Contributor(s): Gervase Markham <gerv@gerv.net>
+
+# Important! The following classes of directives are excluded in the test,
+# and so do not need to be added here. Doing so will cause warnings.
+# See 008filter.t for more details.
+#
+# Comments                        - [%#...
+# Directives                      - [% IF|ELSE|UNLESS|FOREACH...
+# Assignments                     - [% foo = ...
+# Simple literals                 - [% " selected" ...
+# Values always used for numbers  - [% (i|j|k|n|count) %]
+# Params                          - [% Param(...
+# Safe functions                  - [% (time2str|GetBugLink)...
+# Safe vmethods                   - [% foo.size %]
+# TT loop variables               - [% loop.count %]
+# Already-filtered stuff          - [% wibble FILTER html %]
+#   where the filter is one of html|csv|js|url_quote|quoteUrls|time|uri|xml
+
+# Key:
+#
+# "#": directive should be filtered, but not doing so is not a security hole
+# The plan is to come back and add filtering for all those marked "#" after
+# the security release.
+#
+# "# Email": as above; but noting that it's an email address.
+# Other sorts of comments denote cleanups noticed while doing this work;
+# they should be fixed in the very short term.
+
+%::safe = (
+
+'sidebar.xul.tmpl' => [
+  'template_version', 
+],
+
+'search/boolean-charts.html.tmpl' => [
+  '"field${chartnum}-${rownum}-${colnum}"',
+  '"value${chartnum}-${rownum}-${colnum}"',
+  '"type${chartnum}-${rownum}-${colnum}"',
+  'field.name',
+  'field.description',
+  'type.name',
+  'type.description',
+  '"${chartnum}-${rownum}-${newor}"',
+  '"${chartnum}-${newand}-0"',
+  'newchart',
+  '$jsmagic', #
+],
+
+'search/form.html.tmpl' => [
+  'qv.value',
+  'qv.name',
+  'qv.description',
+  'field.name',
+  'field.description',
+  'sel.name',
+  'button_name', #
+],
+
+'search/knob.html.tmpl' => [
+  'button_name', #
+],
+
+'reports/components.html.tmpl' => [
+  'numcols',
+  'numcols - 1',
+  'comp.description',
+  'comp.initialowner', # email address
+  'comp.initialqacontact', # email address
+],
+
+'reports/duplicates-simple.html.tmpl' => [
+  'title', #
+],
+
+'reports/duplicates-table.html.tmpl' => [
+  '"&maxrows=$maxrows" IF maxrows',
+  '"&changedsince=$changedsince" IF changedsince',
+  '"&product=$product" IF product', #
+  '"&format=$format" IF format', #
+  '"&bug_id=$bug_ids_string&sortvisible=1" IF sortvisible',
+  'column.name',
+  'column.description',
+  'vis_bug_ids.push(bug.id)',
+  'bug.id',
+  'bug.count',
+  'bug.delta',
+  'bug.component', #
+  'bug.bug_severity', #
+  'bug.op_sys', #
+  'bug.target_milestone', #
+],
+
+'reports/duplicates.html.tmpl' => [
+  'bug_ids_string',
+  'maxrows',
+  'changedsince',
+  'reverse',
+],
+
+'reports/keywords.html.tmpl' => [
+  'keyword.description',
+  'keyword.bugcount',
+],
+
+'list/change-columns.html.tmpl' => [
+  'column',
+  'desc.${column}', #
+],
+
+'list/edit-multiple.html.tmpl' => [
+  'group.bit',
+  'group.description',
+  'group.description FILTER strike',
+  'knum',
+  'menuname',
+  'selected IF resolution == "FIXED"', #
+],
+
+'list/list-rdf.rdf.tmpl' => [
+  'template_version',
+  'bug.id',
+  'column',
+],
+
+'list/list-simple.html.tmpl' => [
+  'title',
+],
+
+'list/list.html.tmpl' => [
+  'currenttime', #
+  'buglist',
+  'bugowners', # email address
+],
+
+'list/table.html.tmpl' => [
+  'id',
+  'splitheader ? 2 : 1',
+  'abbrev.$id.title || column.title', #
+  'tableheader',
+  'bug.severity', #
+  'bug.priority', #
+  'bug.id',
+],
+
+'global/choose-product.html.tmpl' => [
+  'target',
+  'proddesc.$p',
+],
+
+'global/code-error.html.tmpl' => [
+  'error',
+],
+
+'global/footer.html.tmpl' => [
+  'CALL SyncAnyPendingShadowChanges() IF SyncAnyPendingShadowChanges',
+],
+
+'global/header.html.tmpl' => [
+  'header_html',
+  'javascript',
+  'style',
+  'style_url',
+  'bgcolor',
+  'onload',
+  'h1',
+  'h2',
+  'message',
+],
+
+'global/hidden-fields.html.tmpl' => [
+  'mvalue | html | html_linebreak', # Need to eliminate | usage
+  'field.value | html | html_linebreak',
+],
+
+'global/select-menu.html.tmpl' => [
+  'options', 
+],
+
+'global/useful-links.html.tmpl' => [
+  'user.login', # Email address
+],
+
+'global/user-error.html.tmpl' => [
+  'error', # can contain HTML in 2.16.x
+],
+
+'bug/comments.html.tmpl' => [
+  'comment.time',
+  'quoteUrls(comment.body)',
+],
+
+'bug/dependency-graph.html.tmpl' => [
+  'image_map', # We need to continue to make sure this is safe in the CGI
+  'image_url', 
+  'map_url', 
+  'bug_id', 
+],
+
+'bug/dependency-tree.html.tmpl' => [
+  'hide_resolved ? "Open b" : "B"', 
+  'bugid', 
+  'maxdepth', 
+  'dependson_ids.join(",")', 
+  'blocked_ids.join(",")',
+  'dep_id',
+  'hide_resolved ? 0 : 1',
+  'hide_resolved ? "Show" : "Hide"',
+  'realdepth < 2 || maxdepth == 1 ? "disabled" : ""',
+  'hide_resolved',
+  'realdepth < 2 ? "disabled" : ""',
+  'maxdepth + 1',
+  'maxdepth == 0 || maxdepth == realdepth ? "disabled" : ""',
+  'realdepth < 2 || ( maxdepth && maxdepth < 2 ) ? "disabled" : ""',
+  'maxdepth > 0 && maxdepth <= realdepth ? maxdepth : ""',
+  'maxdepth == 1 ? 1 
+                       : ( maxdepth ? maxdepth - 1 : realdepth - 1 )',
+  'realdepth < 2 || ! maxdepth || maxdepth >= realdepth ?
+            "disabled" : ""',
+],
+
+'bug/edit.html.tmpl' => [
+  'bug.delta_ts',
+  'bug.bug_id',
+  'bug.votes',
+  'group.bit',
+  'group.description',
+  'knum',
+  'dep.title',
+  'dep.fieldname',
+  'bug.${dep.fieldname}.join(\', \')',
+  'selname',
+  'bug.longdesclength',
+  'bug.creation_ts',
+],
+
+'bug/navigate.html.tmpl' => [
+  'this_bug_idx + 1',
+  'bug_list.first',
+  'bug_list.last',
+  'bug_list.$prev_bug',
+  'bug_list.$next_bug',
+],
+
+'bug/show-multiple.html.tmpl' => [
+  'bug.bug_id',
+  'bug.component', #
+  'attr.description', #
+],
+
+'bug/votes/list-for-bug.html.tmpl' => [
+  'voter.count',
+  'total',
+],
+
+'bug/votes/list-for-user.html.tmpl' => [
+  'product.maxperbug',
+  'bug.id',
+  'bug.count',
+  'product.total',
+  'product.maxvotes',
+],
+# h2 = voting_user.name # Email
+
+'bug/process/confirm-duplicate.html.tmpl' => [
+  'original_bug_id',
+  'duplicate_bug_id',
+],
+
+'bug/process/midair.html.tmpl' => [
+  'bug_id',
+],
+
+'bug/process/next.html.tmpl' => [
+  'next_id',
+],
+
+'bug/process/results.html.tmpl' => [
+  'title.$type',
+  'id',
+  'mail',
+],
+
+'bug/process/verify-new-product.html.tmpl' => [
+  'form.product', # 
+],
+
+'bug/create/create.html.tmpl' => [
+  'default.bug_status', #
+  'g.bit',
+  'g.description',
+  'sel.name',
+  'sel.description',
+],
+
+'bug/activity/show.html.tmpl' => [
+  'bug_id',
+],
+
+'bug/activity/table.html.tmpl' => [
+  'operation.who', # Email
+  'operation.when',
+  'change.attachid',
+  'change.field',
+],
+
+'attachment/create.html.tmpl' => [
+  'bugid',
+  'attachment.id',
+],
+
+'attachment/created.html.tmpl' => [
+  'attachid',
+  'bugid',
+  'contenttype',
+  'mailresults',
+],
+
+'attachment/edit.html.tmpl' => [
+  'attachid',
+  'bugid',
+  'def.id',
+  'a',
+],
+
+'attachment/list.html.tmpl' => [
+  'attachment.attachid',
+  'attachment.date',
+  'bugid',
+],
+
+'attachment/show-multiple.html.tmpl' => [
+  'a.attachid',
+  'a.date',
+],
+
+'attachment/updated.html.tmpl' => [
+  'attachid',
+  'bugid',
+  'mailresults',
+],
+
+'admin/attachstatus/create.html.tmpl' => [
+  'id',
+],
+
+'admin/attachstatus/delete.html.tmpl' => [
+  'attachcount',
+  'id',
+  'name',
+],
+
+'admin/attachstatus/edit.html.tmpl' => [
+  'id',
+  'sortkey',
+],
+
+'admin/attachstatus/list.html.tmpl' => [
+  'statusdef.sortkey',
+  'statusdef.id',
+  'statusdef.attachcount',
+],
+
+'account/prefs/account.html.tmpl' => [
+  'login_change_date', #
+],
+
+'account/prefs/email.html.tmpl' => [
+  'watchedusers', # Email
+  'useqacontact ? \'5\' : \'4\'',
+  'role',
+  'reason.name',
+  'reason.description',
+],
+
+'account/prefs/permissions.html.tmpl' => [
+  'bit_description',
+],
+
+'account/prefs/prefs.html.tmpl' => [
+  'tab.name',
+  'tab.description',
+  'changes_saved',
+  'current_tab.name',
+  'current_tab.description',
+  'current_tab.description FILTER lower',
+],
+
+);
index e8d9aaf5c0f596485fb106e623844d3c8b702ff7..530413de65d9102e6e6cee75c2c2ee2c03a80151 100644 (file)
@@ -33,7 +33,7 @@
   <tr>
     <th align="right" valign="top">
       <a href="[% target %]?product=[% p FILTER url_quote %]
-                                       [%- "&amp;format=$format" IF format %]">
+            [% IF format %]&amp;format=[% format FILTER url_quote %][% END %]">
       [% p FILTER html %]</a>:
     </th>
 
index 637fba6b1bb3dedb87513c4a37e3e9acceb64254..cab4f44b8a6fe586819794e5a51a56b56a2b4e9e 100644 (file)
@@ -56,7 +56,7 @@
   <pre>
 Variables:
   [% FOREACH key = variables.keys %]
-    [%+ key %]: [%+ variables.$key %]
+    [%+ key FILTER html %]: [%+ variables.$key FILTER html %]
   [% END %]
   </pre>
 [% END %]
index f968fab200d78217c94adea21febff65a4ac8945..a824c3489cb689c382d3290822a1c276bb2afcb1 100644 (file)
   [% NEXT IF exclude && field.key.search(exclude) %]
   [% IF mform.${field.key}.size > 1 %]
     [% FOREACH mvalue = mform.${field.key} %]
-      <input type="hidden" name="[% field.key %]"
+      <input type="hidden" name="[% field.key FILTER html %]"
              value="[% mvalue | html | html_linebreak %]">
     [% END %]
   [% ELSE %]
-    <input type="hidden" name="[% field.key %]"
+    <input type="hidden" name="[% field.key FILTER html %]"
            value="[% field.value | html | html_linebreak %]">
   [% END %]
 [% END %]
index 14e1f10d0343784f1bdd1657ed0fb78cb8cebb9f..f1f77fdb214dec62e023bbb002429e63a90e4aa9 100644 (file)
@@ -35,7 +35,7 @@
 [%# Display a URL if the calling script has included one. %]
 [% IF url && link %]
   <p>
-    <a href="[% url %]">[% link %]</a>
+    <a href="[% url FILTER html %]">[% link FILTER html %]</a>
   </p>
 [% END %]
 
index 96e56e8eb95c1e9555970f372842fe29b76bf8fa..a7c5f6e2351605dc460bceee28de6f2d23f32688 100644 (file)
@@ -27,7 +27,7 @@ Check which columns you wish to appear on the list, and then click
 on submit.  (Cookies are required.)
 <p>
 <form action="colchange.cgi">
-<input type="hidden" name="rememberedquery" value="[% buffer %]">
+<input type="hidden" name="rememberedquery" value="[% buffer FILTER html %]">
 [% FOREACH column = masterlist %]
   <input type="checkbox" id="[% column %]" name="column_[% column %]" [% "CHECKED" IF lsearch(collist, column) != -1 %]>
   <label for="[% column %]">[% desc.${column} %]</label><br>
@@ -41,7 +41,7 @@ on submit.  (Cookies are required.)
 <input type="submit" value="Submit">
 </form>
 <form action="colchange.cgi">
-<input type="hidden" name="rememberedquery" value="[% buffer %]">
+<input type="hidden" name="rememberedquery" value="[% buffer FILTER html %]">
 <input type="hidden" name="resetit" value="1">
 <input type="submit" value="Reset to Bugzilla default">
 </form>
index 8ffba004fb16f332382deaeee1172ad306e328a1..dab76666fce2687839cdc5209f7c6513ea212091 100644 (file)
@@ -94,7 +94,7 @@
   <p>
     <a href="query.cgi">Query Page</a>
     &nbsp;&nbsp;<a href="enter_bug.cgi">Enter New Bug</a>
-    <a href="query.cgi?[% urlquerypart %]">Edit this query</a>
+    <a href="query.cgi?[% urlquerypart FILTER html %]">Edit this query</a>
   </p>
 
 [% ELSIF bugs.size == 1 %]
 
     <a href="query.cgi">Query Page</a> &nbsp;&nbsp;
     <a href="enter_bug.cgi">Enter New Bug</a> &nbsp;&nbsp;
-    <a href="colchange.cgi?[% urlquerypart %]">Change Columns</a> &nbsp;&nbsp;
+    <a href="colchange.cgi?[% urlquerypart FILTER html %]">Change Columns</a> &nbsp;&nbsp;
 
     [% IF bugs.size > 1 && caneditbugs && !dotweak %]
-      <a href="buglist.cgi?[% urlquerypart %]
+      <a href="buglist.cgi?[% urlquerypart FILTER html %]
         [%- "&order=$qorder" FILTER html IF order %]&amp;tweak=1">Change Several 
         Bugs at Once</a>
       &nbsp;&nbsp;
       <a href="mailto:[% bugowners %]">Send Mail to Bug Owners</a> &nbsp;&nbsp;
     [% END %]
 
-    <a href="query.cgi?[% urlquerypart %]">Edit this Query</a> &nbsp;&nbsp;
+    <a href="query.cgi?[% urlquerypart FILTER html %]">Edit this Query</a> &nbsp;&nbsp;
 
   </form>
 
index 6d5ee0d6cc11397f13761b5cb86e53a3aa9ab521..f14784f65c23b2f02b1ad7b236b488db46c8d4f8 100644 (file)
@@ -69,7 +69,7 @@
 
     <tr align="left">
       <th colspan="[% splitheader ? 2 : 1 %]">
-        <a href="buglist.cgi?[% urlquerypart %]&amp;order=bugs.bug_id">ID</a>
+        <a href="buglist.cgi?[% urlquerypart FILTER html %]&amp;order=bugs.bug_id">ID</a>
       </th>
 
       [% IF splitheader %]
 
 [% BLOCK columnheader %]
   <th colspan="[% splitheader ? 2 : 1 %]">
-    <a href="buglist.cgi?[% urlquerypart %]&amp;order=
+    <a href="buglist.cgi?[% urlquerypart FILTER html %]&amp;order=
       [% column.name FILTER url_quote FILTER html %]
       [% ",$qorder" FILTER html IF order %]">
         [%- abbrev.$id.title || column.title -%]</a>
index 64ba5e120d56eb02b40b551f4d12931bd322b618..da218d7c55af6cfebb8b549a2ecfab35d9d1d177 100644 (file)
@@ -59,7 +59,7 @@
 <h3><a name="params">Change Parameters</a></h3>
 
 <form method="get" action="duplicates.cgi">
-  <input type="hidden" name="sortby" value="[% sortby %]">
+  <input type="hidden" name="sortby" value="[% sortby FILTER html %]">
   <input type="hidden" name="reverse" value="[% reverse %]">
   <input type="hidden" name="bug_id" value="[% bug_ids_string %]">
   <table>
@@ -83,8 +83,8 @@
       <td rowspan="4" valign="top">
         <select name="product" size="5" multiple="multiple">
           [% FOREACH p = products %]
-            <option name="[% p %]"
-            [% " selected" IF product == p %]>[% p %]</option>
+            <option name="[% p FILTER html %]"
+            [% " selected" IF product == p %]>[% p FILTER html %]</option>
           [% END %]
         </select>
       </td>