Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Taint, CGI and perl 5.10

by nextguru (Scribe)
on Mar 10, 2010 at 19:49 UTC ( #827881=perlquestion: print w/replies, xml ) Need Help??
nextguru has asked for the wisdom of the Perl Monks concerning the following question:

I have several CGI scripts running with the -T flag that have broken after recently upgrading the perl installation from 5.8 to 5.10 on my development web server. The problem is when writing tainted information to a filehandle with a formerly tainted file name. This makes no sense to me, but untainting the information being written to the file gets rid of the 'Insecure dependency in printf...' messages.

What am I missing that writing tainted data is now a problem?

Replies are listed 'Best First'.
Re: Taint, CGI and perl 5.10
by ikegami (Pope) on Mar 10, 2010 at 21:22 UTC
    Demo code, please. Your description is inaccurate (file handles don't have file names), and I can't reproduce the problem by guessing what you meant.
    $ perl -Te' my $fn = $ARGV[0]; ($fn) = $fn =~ /^([a-zA-Z0-9]{1,8}\.txt)\z/ or die; open(my $fh, ">", $fn) or die; printf $fh "%s\n", "foo"; ' foo.txt $ cat foo.txt foo

    Update: Oops, missed the bit about writing tainted info, but it makes no difference

    $ perl -Te' my $fn = $ARGV[0]; ($fn) = $fn =~ /^([a-zA-Z0-9]{1,8}\.txt)\z/ or die; open(my $fh, ">", $fn) or die; printf $fh "%s\n", $ARGV[0]; ' foo.txt $ cat foo.txt foo.txt $ perl -Te' my $fn = $ARGV[0]; ($fn) = $fn =~ /^([a-zA-Z0-9]{1,8}\.txt)\z/ or die; open(my $fh, ">", $fn) or die; print $fh $ARGV[0]; print $fh "\n"; ' foo.txt $ cat foo.txt foo.txt
      The following code exhibits the trouble.
      #!/usr/bin/perl -wT use strict my $tainteddata = $ARGV[0]; my ($untainteddata) = $tainteddata =~ /^([\w]+)$/; open(my $fh, ">", $untainteddata) or die; printf $fh <<EOMEOM; removing the next line of output allows the script to work the tainted data: $tainteddata script works with or without the following line the untainted data: $untainteddata EOMEOM close ($fh); exit;
      In trying other solutions, I've determined that the here document appears to be the culprit. The following code works fine.
      #!/usr/bin/perl -wT use strict; my $tainteddata = $ARGV[0]; my ($untainteddata) = $tainteddata =~ /^([\w]+)$/; open(my $fh, ">", $untainteddata) or die; printf $fh $tainteddata, "\n"; close ($fh); exit;
      This is curious to me. Why the different behavior for here documents? Original version of perl was 5.8.9, now 5.10.1.

        Your problem can be demonstrated using

        perl -Te'printf $ARGV[0]' foo

        The first argument of printf (optional fh aside) is the format pattern. It makes sense to require the pattern to be trusted. Consider %n, for example.

        printf $fh <<EOMEOM;
        should be
        printf $fh "%s", <<EOMEOM;
        or simply
        print $fh <<EOMEOM;

        Your code is buggy, and 5.10 catches your bug.

        perldoc perl595delta says

        When perl is run under taint mode, printf() and sprintf() will now reject any tainted format argument.

      I will try to cut the code down to the smallest instance where the problem still occurs and repost in a bit. Essentially the problem is this:

      • using perl 5.8
      • code working with taint mode turned on, file name comes from user, untainted by code and tainted information written to file successfully.
      • upgrade to 5.10
      • code now broken with 'insecure dependency...' error
      • only way to fix is to untaint the information written to the file. Nothing else changed.
      I pass a file handle and the tainted information to a subroutine that does the output. I don't know if that makes a difference. Back in a bit with code sample.
        The above does exactly what you said except it gives no error with 5.10.0.
Re: Taint, CGI and perl 5.10
by SilasTheMonk (Chaplain) on Mar 10, 2010 at 21:08 UTC
    What I fail to understand is why it worked under perl 5.8. The purpose of taint mode is to capture potentially dangerous information before it affects your machine or you. Writing to a file handle (which could be any thing from your /etc/passwd to a socket to your bank's webserver) comes into that category. My suspicion is that from time to time you turn off taint mode on development machines (as I do) and this muddied the waters.
Re: Taint, CGI and perl 5.10
by BrowserUk (Pope) on Mar 10, 2010 at 19:56 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://827881]
Approved by Corion
Front-paged by MidLifeXis
[Corion]: Yaerox: That's a somewhat hard problem. Encode solves the conversion part, but for guessing what encoding a file is in, that's the hard part
[Corion]: Yaerox: There is Encode::Guess, but that needs a limited set of inputs, and it also cannot handle multiple single-byte encodings
[Corion]: If you have a BOM, that's a really easy way to recognize UTF-8. Otherwise, you can try to decode a file from UTF-8, and if that works OK and doesn't crash, most likely the file was valid UTF-8
[Corion]: But as "ansi" (Latin-1?) is a single-byte encoding, any file is a valid ANSI file

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2017-03-28 13:19 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (332 votes). Check out past polls.