Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Comment on

by gods
on Feb 11, 2000 at 00:06 UTC ( #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":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

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

    How do I use this? | Other CB clients
    Other Users?
    Others meditating upon the Monastery: (3)
    As of 2016-09-25 19:12 GMT
    Find Nodes?
      Voting Booth?
      Extraterrestrials haven't visited the Earth yet because:

      Results (472 votes). Check out past polls.