Subject: | new option force_untaint |
This patch to HTML::Template 2.8 (attached) adds a new option
"force_untaint". If the option is set, you can no longer pass untainted
values to paramters with param().
perl has to run in taint mode (-T).
Subject: | force_untaint.patch |
diff -dur --unidirectional-new-file HTML-Template-2.8.orig/Changes HTML-Template-2.8/Changes
--- HTML-Template-2.8.orig/Changes 2005-12-22 00:37:49.000000000 +0100
+++ HTML-Template-2.8/Changes 2006-11-24 14:55:08.000000000 +0100
@@ -1,3 +1,6 @@
+ - New Feature: the new force_untaint option makes sure you do not
+ pass tainted values to param(). [Sven Neuhaus]
+
2.8 Wed Dec 21 18:37:39 EST 2005
- New Feature: the new default_escape option allows you to apply
escaping to all variables in a template. [Alex Kapranoff]
diff -dur --unidirectional-new-file HTML-Template-2.8.orig/MANIFEST HTML-Template-2.8/MANIFEST
--- HTML-Template-2.8.orig/MANIFEST 2005-12-22 00:34:42.000000000 +0100
+++ HTML-Template-2.8/MANIFEST 2006-11-24 15:05:07.000000000 +0100
@@ -11,6 +11,8 @@
t/01coderefs.t
t/02random.t
t/03else_else_bug.t
+t/04no_taintmode.t
+t/05force_untaint.t
t/99-old-test-pl.t
Template.pm
templates/case_loop.tmpl
diff -dur --unidirectional-new-file HTML-Template-2.8.orig/Makefile.PL HTML-Template-2.8/Makefile.PL
--- HTML-Template-2.8.orig/Makefile.PL 2004-08-05 19:50:51.000000000 +0200
+++ HTML-Template-2.8/Makefile.PL 2006-11-24 14:54:12.000000000 +0100
@@ -29,5 +29,6 @@
'File::Spec' => 0.82,
'Digest::MD5'=> 0,
'Test::More' => 0,
+ 'Scalar::Util' => 0,
},
);
diff -dur --unidirectional-new-file HTML-Template-2.8.orig/Template.pm HTML-Template-2.8/Template.pm
--- HTML-Template-2.8.orig/Template.pm 2005-12-22 00:21:01.000000000 +0100
+++ HTML-Template-2.8/Template.pm 2006-11-24 15:36:50.000000000 +0100
@@ -475,6 +475,13 @@
=item *
+force_untaint - if set to 1 the module will not allow you
+to set parameters with tainted values. This option makes sure you untaint
+everything so you don't accidentally introduce e.g. cross-site-scripting
+(CSS) vulnerabilities. Requires taint mode. Defaults to 0.
+
+=item *
+
strict - if set to 0 the module will allow things that look like they
might be TMPL_* tags to get by without dieing. Example:
@@ -898,6 +905,7 @@
use Carp; # generate better errors with more context
use File::Spec; # generate paths that work on all platforms
use Digest::MD5 qw(md5_hex); # generate cache keys
+use Scalar::Util qw(tainted);
# define accessor constants used to improve readability of array
# accesses into "objects". I used to use 'use constant' but that
@@ -942,6 +950,7 @@
file_cache => 0,
file_cache_dir => '',
file_cache_dir_mode => 0700,
+ force_untaint => 0,
cache_debug => 0,
shared_cache_debug => 0,
memory_debug => 0,
@@ -1005,6 +1014,11 @@
delete $options->{source};
}
+ # make sure taint mode is on if force_untaint flag is set
+ if ($options->{force_untaint} && ! ${^TAINT}) {
+ croak("HTML::Template->new() : 'force_untaint' option set but perl does not run in taint mode!");
+ }
+
# associate should be an array of one element if it's not
# already an array.
if (ref($options->{associate}) ne 'ARRAY') {
@@ -2463,6 +2477,9 @@
}
);
+An error occurs if you try to set a value that is tainted if the "force_untaint"
+option is set.
+
=cut
@@ -2531,6 +2548,9 @@
} else {
(ref($param_map->{$param}) eq 'HTML::Template::VAR') or
croak("HTML::Template::param() : attempt to set parameter '$param' with a scalar - parameter is not a TMPL_VAR!");
+ if ($options->{force_untaint} && tainted($value)) {
+ croak("HTML::Template::param() : attempt to set parameter '$param' with a tainted value")
+ }
${$param_map->{$param}} = $value;
}
}
diff -dur --unidirectional-new-file HTML-Template-2.8.orig/t/04no_taintmode.t HTML-Template-2.8/t/04no_taintmode.t
--- HTML-Template-2.8.orig/t/04no_taintmode.t 1970-01-01 01:00:00.000000000 +0100
+++ HTML-Template-2.8/t/04no_taintmode.t 2006-11-24 15:02:13.000000000 +0100
@@ -0,0 +1,16 @@
+
+use Test::More tests => 1;
+use HTML::Template;
+
+my $text = qq{foo};
+
+eval {
+ my $template = HTML::Template->new(
+ debug => 0,
+ scalarref => \$text,
+ force_untaint => 1,
+ );
+};
+
+like($@, qr/script does not run in taint mode/,
+ "force_untaint does not work without taint mode");
diff -dur --unidirectional-new-file HTML-Template-2.8.orig/t/05force_untaint.t HTML-Template-2.8/t/05force_untaint.t
--- HTML-Template-2.8.orig/t/05force_untaint.t 1970-01-01 01:00:00.000000000 +0100
+++ HTML-Template-2.8/t/05force_untaint.t 2006-11-24 15:03:38.000000000 +0100
@@ -0,0 +1,22 @@
+#!perl -T
+
+use Test::More tests => 1;
+use HTML::Template;
+
+my $text = qq{ <TMPL_VAR NAME="a"> };
+
+my $template = HTML::Template->new(
+ debug => 0,
+ scalarref => \$text,
+ force_untaint => 1,
+);
+
+# We can't manually taint a variable, can we?
+# OK, let's use ENV{PATH} - it is usually tainted [sn]
+
+eval {
+ $template->param(a => $ENV{PATH} );
+};
+
+like($@, qr/attempt to set parameter 'a' with a tainted value/,
+ "set tained value despite option force_untaint");