Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Why a taint flag on test files?

by xdg (Monsignor)
on Oct 13, 2005 at 18:42 UTC ( #499986=perlquestion: print w/ replies, xml ) Need Help??
xdg has asked for the wisdom of the Perl Monks concerning the following question:

In looking at some test files on CPAN recently, I've noticed several with a taint flag in the "shebang" line:

#!/usr/bin/perl -T use Test::More;

For example, this is the default for the pod.t and pod-coverage.t files from Module::Starter::PBP -- though not, apparently, for regular .t files generated that way.

What's the idea behind flagging .t files for taint checking? Any good rules of thumb for when it's the right thing to do? I wouldn't have thought it a necessity for a test script, unless the test was specifically testing the taint-safe behavior of something.

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Comment on Why a taint flag on test files?
Download Code
Re: Why a taint flag on test files?
by scmason (Monk) on Oct 13, 2005 at 19:16 UTC
    From a users perspective, it is a good thing to know that the test script is not going to do anything odd with your personel system/data.

    It is most likely that the taint checking was turned on because a lot of people will ague that it is always a good idea unless you have a specific reason not too. From the philosophy "Make your error on the side of caution" school of thought.

    "Never take yourself too seriously, because everyone knows that fat birds dont fly" -FLC
      From a users perspective, it is a good thing to know that the test script is not going to do anything odd with your personel system/data.

      That's not what taint mode does, though -- it flags external data, not internal data. A test script could very well do this evil thing:

      WARNING -- Don't try this at home.

      #!/usr/bin/perl -T #### DO NOT ACTUALLY RUN THIS CODE #### use Test::More tests => 1; use File::Path; use File::Spec; my $n = rmtree( File::Spec->rootdir(), 0, 1); ok( $n, "Deleted at least one file from the root directory" );

      Sadly, Perl doesn't have a nice sandbox like Java. Good reason not build/test modules as root, eh?

      What the taint flag will do is limit the directories in @INC. From perlsec:

      When the taint mode ("-T") is in effect, the "." directory is removed from @INC, and the environment variables "PERL5LIB" and "PERLLIB" are ignored by Perl. You can still adjust @INC from outside the program by using the "-I" command line option as explained in perlrun. The two environment variables are ignored because they are obscured, and a user running a program could be unaware that they are set, whereas the "-I" option is clearly visible and therefore permitted.

      For testing, I'm still not sure if that is or isn't desireable. What if a user has their own private installation in PERL5LIB?

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        For testing, I'm still not sure if that is or isn't desireable. What if a user has their own private installation in PERL5LIB?
        Then make test fails because the current setup will not work under taint. Which is better then letting CPAN install it, and then find out your program isn't going to work under taint.

        The user has some options though. He can abandon the attempts to install it. He can install whatever is in his private installation in the standard directories. He can recompile perl to have his PERL5LIB part of the default @INC - perhaps by creating a private perl installation. He can make sure the directories of his PERL5LIB are put as -I arguments when the test scripts are called. He can modify the test scripts to include the relevant directories in @INC. He can modify the test scripts and remove the -T or -t options.

        It's a delicate issue. Should you, or shouldn't you run tests with taint enabled? Not because the environment is untrusted, but because the purpose of tests is to show the module works correctly. And that would include running correctly with taint enabled.

        Perl --((8:>*
Re: Why a taint flag on test files?
by dave_the_m (Parson) on Oct 13, 2005 at 21:02 UTC
    The obvious reason for testing that a module works under taint is that at some point someone might try to use your module within a taint-enabled program.

    Dave.

      Testing a module under taint, I get. But on every test file? Even ones like pod-coverage that aren't running any code of yours? And if it's a good practice, why wouldn't that be the default for boilerplate-generated test scripts?

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Why a taint flag on test files?
by eyepopslikeamosquito (Canon) on Oct 14, 2005 at 09:05 UTC

    Generally, I like to run all my tests both in normal mode and taint mode. And the prove command's -T switch is very handy for that. By doing that, I can ensure that my module will work from a taint mode program.

    Not only that, but verifying that your tests run the same both in normal mode and taint mode can uncover bugs in perl itself, since taint mode has historically been a source of perl bugs and weird differences in behaviour.

    The trouble with -T is that "make test" runs the test in taint mode only. I wish there was some way to tell it to run a test twice: once in normal mode and once in taint mode.

    To further ensure that your module works in still broader environments, it would be nice to test that it works fine in "persistent" environments, such as mod_perl (e.g. a module that uses an INIT block will not be mod_perl-safe). I don't know of an easy way to test that a module is "persistent-environment-safe".

      Ideally, you should run your tests with a 32bit and a 64bit perl, with threads and without threads enabled (that is, threads enabled in *perl*, doesn't mean your code actually uses threads), with blead-perl, maint-perl and a selection of older versions of perl (5.8.1, 5.8.0, 5.6.2, ...). With and without taint-checking enabled. With and without PERL_HASH_SEED set. With and without PERL_SIGNALS set to unsafe. All possibilites for -C (or PERL_UNICODE). And in all combinations.
      Perl --((8:>*
      To further ensure that your module works in still broader environments, it would be nice to test that it works fine in "persistent" environments, such as mod_perl (e.g. a module that uses an INIT block will not be mod_perl-safe). I don't know of an easy way to test that a module is "persistent-environment-safe".

      According to perlmod, CHECK and INIT blocks are not executed in a string eval. So something like this should work:

      use Test::More 'no_plan'; eval "require My::Module; My::Module->import()"; # test behaviors without INIT/CHECK

      Of course, you'd have to duplicate your test files to be sure of all behavior, but I'd probably tackle that by putting all the tests into helper libraries and then the duplication isn't quite so painful.

      # t/Test/BehaviorA.pm package t::Test::BehaviorA; use base 'Exporter'; use vars qw(@EXPORT); @EXPORT = qw( run_tests_for_A ); use Test::More tests => 42; sub run_tests_for_A { # put 42 tests for Behavior A here } 1; # need this
      # 01-test-A-normal.t use t::Test::BehaviorA qw( run_tests_for_A ); use My::Module; run_tests_for_A();
      # 01-test-A-persistant.t use t::Test::BehaviorA qw( run_tests_for_A ); eval "require My::Module; My::Module->import()"; run_tests_for_A();

      This kind of thing starts to beg for using something like Test::Class, perhaps.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Why a taint flag on test files?
by adrianh (Chancellor) on Oct 14, 2005 at 11:26 UTC
    What's the idea behind flagging .t files for taint checking?

    I write most of my code with tainting enabled, so I want to make sure everything works with tainting enabled. It makes my life easier if other people do it too :-)

    Any good rules of thumb for when it's the right thing to do?

    My default is to always have tainting on.

    I wouldn't have thought it a necessity for a test script, unless the test was specifically testing the taint-safe behavior of something.

    And how do you know which bits of your code (and any of its dependencies) relate to taint safe behaviour? :-)

    You can either spend a lot of time and effort figuring it out yourself, or you can just tack '-T' to your perl line and get perl to figure it out for you.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://499986]
Approved by herveus
Front-paged by sk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (8)
As of 2014-08-27 09:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (234 votes), past polls