Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Perl have nice feature called taint mode which helps developers to write more secure code by forcing them to carefully verify all input. However it doesn't help to prevent certain type of security vulnerabilities like XSS because this type of security vulnerabilities happen when developer doesn't verify and escape output. On first look it seems that taint mode is useless to force checking of output. But I was still thinking if it is really useless in this case. And I've got this idea: how about implementing an additional layer between web applications and its clients which would assure that tainted data cannot pass into web application's output. As result of this meditation I've come up with this merely proof-of-concept implementation which works with Template::Toolkit based applications.

package Template::Secure; use strict; use warnings; use base qw(Template); use Carp; use Scalar::Util qw(tainted); # simplified version of Template's process method which only supports # output to STDOUT sub process { my ($self, $template, $vars) = @_; my $output = ''; my $ret = $self->SUPER::process($template, $vars, \$output); if(tainted $output) { croak("Insecure dependency in Template::Secure->process()"); } print $output; return $ret; }

This is almost drop-in replacement module for Template module which will complain if it notices any tainted data in output. Another missing piece is convenient plugin for Template which would implement HTML/URL escaping in output and untaint escaped strings at same time. Template toolkit provides two plugins useful to do escaping of strings in HTML: Template::Plugin::URL and Template::Plugin::HTML. They only have to be slighly changed to untaint escaped strings.

# a bit hacky way to redefine subs without modifying sources; this # code can be put directly into Template::Secure module { require Template::Plugin::URL; require Template::Plugin::HTML; no warnings 'redefine'; my $url_escape_sub = \&Template::Plugin::URL::escape; *Template::Plugin::URL::escape = sub { my $ret = $url_escape_sub->(@_); $ret =~ /(.*)/; # untaints string return $1; }; my $html_escape_sub = \&Template::Plugin::HTML::escape; *Template::Plugin::HTML::escape = sub { my $ret = $html_escape_sub->(@_); $ret =~ /(.*)/; # untaints string return $1; }; }

Now example application: nearly hello world :).

#!/usr/bin/perl -T # First version which has XSS hole and doesn't work thanks to taint # checks in Template::Secure use strict; use warnings; use CGI; use Template::Secure; my $query = CGI->new; my $name = $query->param('name') || 'World'; my $tt = Template::Secure->new; print $query->header; $tt->process(\*DATA, { name => $name }) || die $tt->error(), "\n"; __END__ <html> <head> <title>Sample program</title> </head> <body> Hello, [% name %]! </body> </html>
#!/usr/bin/perl -T # Second version which is XSS free use strict; use warnings; use CGI; use Template::Secure; my $query = CGI->new; my $name = $query->param('name') || 'World'; my $tt = Template::Secure->new; print $query->header; $tt->process(\*DATA, { name => $name }) || die $tt->error(), "\n"; __END__ [% USE HTML %] <html> <head> <title>Sample program</title> </head> <body> Hello, [% HTML.escape(name) %]! </body> </html>

P.S. Note that it is merely proof-of-concept just to show the idea. There are probably some missing pieces (for example real implementation should untaint templates which are read by Template Toolkit from filesystem). And I'm sure same idea can be ported to other templating modules.

Ilya Martynov,
Quality Perl Programming and Unix Support UK managed @ offshore prices -
Personal website -

In reply to Using taint mode to prevent XSS holes by IlyaM

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (4)
As of 2022-10-06 22:50 GMT
Find Nodes?
    Voting Booth?
    My preferred way to holiday/vacation is:

    Results (29 votes). Check out past polls.