Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

When not to use taint mode

by Bod (Deacon)
on Jun 12, 2021 at 19:09 UTC ( #11133811=perlquestion: print w/replies, xml ) Need Help??

Bod has asked for the wisdom of the Perl Monks concerning the following question:

A few times recently in the Monastery I have noticed mention of taint mode

A long time ago I first came across taint mode and decided it is far too difficult to understand...I've since looked again and it doesn't appear anything like as mystical as it once did. That's what happens when one improves of course.

I have never used taint mode so have no idea of the ease or otherwise of actually using it. It seems from this poll that most others don't use it either. So why not? Is it that taint mode is actually difficult to use or are there reasons to keep it switched off as it is by default?

Do you have any advice on the topic?

Replies are listed 'Best First'.
Re: When not to use taint mode
by afoken (Canon) on Jun 12, 2021 at 20:48 UTC
    A long time ago I first came across taint mode and decided it is far too difficult to understand...I've since looked again and it doesn't appear anything like as mystical as it once did. That's what happens when one improves of course.

    Taint mode is actually quite simple:

    First, data fetched from external sources is marked as tainted. The exact list is found in perlsec:

    All command line arguments, environment variables, locale information (see perllocale), results of certain system calls (readdir(), readlink(), the variable of shmread(), the messages returned by msgrcv(), the password, gcos and shell fields returned by the getpwxxx() calls), and all file input are marked as "tainted".

    Expect that list to grow over time.

    Second, passing tainted data to some critical functions causes a runtime error. The description is again found in perlsec:

    Tainted data may not be used directly or indirectly in any command that invokes a sub-shell, nor in any command that modifies files, directories, or processes, with the following exceptions:

    • Arguments to print and syswrite are not checked for taintedness.
    • Symbolic methods
      $obj->$method(@args);
      and symbolic sub references
      &{$foo}(@args); $foo->(@args);
      are not checked for taintedness. This requires extra carefulness unless you want external data to affect your control flow. Unless you carefully limit what these symbolic values are, people are able to call functions outside your Perl code, such as POSIX::system, in which case they are able to run arbitrary external code.
    • Hash keys are never tainted.

    Third, almost all operations on tainted data will also taint the result. The exceptions are the ternary condition opperator ?: (see perlipc for the rationale), and references to subpatterns from a regular expression match. Again quoting perlpic:

    But testing for taintedness gets you only so far. Sometimes you have just to clear your data's taintedness. Values may be untainted by using them as keys in a hash; otherwise the only way to bypass the tainting mechanism is by referencing subpatterns from a regular expression match. Perl presumes that if you reference a substring using $1, $2, etc. in a non-tainting pattern, that you knew what you were doing when you wrote that pattern. That means using a bit of thought--don't just blindly untaint anything, or you defeat the entire mechanism. It's better to verify that the variable has only good characters (for certain values of "good") rather than checking whether it has any bad characters. That's because it's far too easy to miss bad characters that you never thought of.

    So, these three facts combined prevent you from passing untrustworthy data to functions relevant to system integrity. You explicitly have to check all relevant incoming data. If you forget to check at one point, your script will die instead of doing dangerous things.

    Some modules handle also taint mode. DBI optionally taints most data read from the database, and optionally checks for tainted parameters. CGI explicitly taints all multi-part form data, all other input is already tainted by perl. File::Find can automatically untaint directory names. Other modules may or may not handle taint mode.

    Taint mode is usually enabled by passing the -T argument to the interpreter. Perl automatically enables taint mode when it detects it is running with differing real and effective user or group IDs. perlipc explains when to enable taint mode:

    [Taint mode] is strongly suggested for server programs and any program run on behalf of someone else, such as a CGI script.

    It does not hurt to enable taint mode in more situations. Running a perl script as root is a strong indicator that you want to enable taint mode, as is almost any script handling data from the network or other non-trustworthy sources. If in doubt, enable taint mode.

    Taint mode for DBI is an interesting question: If only your script interacts with the database, and if you use placeholders everywhere, the database could be considered trustworthy. I would not trust the database if it is reachable from the network. Again, if in doubt, enable taint mode and make DBI taint data from the database and check DBI method calls for tainted data (attributes Taint, TaintIn, TaintOut).

    Update:

    Note that $ENV{'PATH'} is tainted, and so any attempt to run external programs will fail with Insecure $ENV{PATH}. You need to set $ENV{'PATH'} to an untainted value, and you should delete some other critial environment variables. perlipc recommends:

    delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer

    A sane value for $ENV{'PATH'} is usally /bin:/usr/bin, but that depends on the target system.

    Also note that if use locale is in effect, the pattern \w depends on the locale, the locale data is tainted, any regular expression containing \w is tainted, and thus untainting using a regular expression containing \w won't work.

    And finally the big fat warning: Taint mode does not magically make your script secure. It just prevents some common errors. You still need to think about what your code does. You need to be paranoid about the data you are working with. Taint mode just helps you find common problems.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Thank you for such a comprehensive and informative answer.

      Taint mode is strongly suggested for server programs and any program run on behalf of someone else, such as a CGI script

      As most of my Perl programming runs on a webserver, and most of that in a CGI context, I guess I should be turning on taint mode!

Re: When not to use taint mode
by hippo (Chancellor) on Jun 12, 2021 at 20:23 UTC

    I always use taint mode when running with elevated privileges (or in a script which is expected to be so run). Similarly I always use taint mode in anything which is public-facing because sooner or later a kiddie will try to root it.

    Since those criteria account for maybe 80% of the work that I do, I am one of the very few who voted "More often than not" in that poll. YMMV, of course.


    🦛

Re: When not to use taint mode
by BillKSmith (Prior) on Jun 13, 2021 at 20:46 UTC
    Taint mode is much like use strict and use warnings in that it alerts us to conditions which we should have recognized without help. However, messages from the first two usually mean that our code does not do what we intend. Taint messages indicate a security problem. Most of us feel that we can ignore that until "everything else is working". (When is that?) Security problems are frequently difficult to solve, especially when they have been ignored until the end of a project. There certainly is a temptation to use a 'quick fix' which gets rid of the message, but does little or nothing to enhance security. There is not much sense in using any of these tools unless we are willing to make meaningful corrections. With this is mind, I always use the first two, but never use taint.
    Bill
Re: When not to use taint mode
by eyepopslikeamosquito (Bishop) on Jun 14, 2021 at 00:56 UTC

    Since you've recently contributed a CPAN module (Business::Stripe::WebCheckout) you might like to verify that it works flawlessly in taint mode. After all, some of your users might want to call your superb module from a taint mode script.

    Ideally, CPAN modules should be tested with and without taint (though I don't know if CPAN testers currently do that). Note that you can run your module's tests in taint mode via the Test::Harness prove utility's -T and -t switches.

      you might like to verify that it works flawlessly in taint mode

      Understanding how to use taint mode and practically doing so are high on my todo list.
      Once I am clear about that, I shall test the only module I have on CPAN.

      Just to check my understanding - because taint mode is turned on when Perl is called, turning it on for the script will turn it on for everything including every module that is used by the script. Is that correct?

        turning it on for the script will turn it on for everything including every module that is used by the script. Is that correct?

        Correct. eg:

        $ cat ptt.pl use strict; use warnings; use Path::Tiny; path ($ARGV[0])->spew (@ARGV); $ perl -T ptt.pl foo Insecure dependency in sysopen while running with -T switch at /usr/sh +are/perl5/vendor_perl/Path/Tiny.pm line 830. $

        It would be of rather limited use otherwise.


        🦛

Re: When not to use taint mode
by jo37 (Hermit) on Jun 12, 2021 at 19:41 UTC

    I can only answer the inverse question. But as I am mainly a Perl hobbyist, this is virtually irrelevant. I use taint mode whenever I do something dangerous: particularly string evals.

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
Re: When not to use taint mode
by shmem (Chancellor) on Jun 14, 2021 at 05:51 UTC

    One argument against taint mode which surfaces every now and then is: "nah, the stuff I write is strictly for internal services/use only, it doesn't interact with the internet, so I don't need taint mode."

    Which is wrong.

    As if all insiders were saints or at least sane all of the time.
    As if neither they, nor you, would ever be stupid.
    As if most of the attacks against company infrastructure didn't come from the inside.

    Taint mode is a wonderful way of preventing others - and yourself! - from doing something stupid.
    Taint mode enforces good practice.

    So, there's no good reason not to use it, but lazyness and impatience. But then, think hubris.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      > So, there's no good reason not to use it, but lazyness and impatience.

      I disagree, it always depends on the use case.

      If I just write a script which converts one text file into another, it's overkill.

      If I write a CGI or something with root rights or generally with foreign user input, it's mandatory.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      PS: it's more or less the same reason why we don't use strict on one-liners.

        Okay,okay - no such thing as something obvious.

        If I just write a script which converts one text file into another, it's overkill.

        And certainly this applies for one-liners also. I've never started a one-liner with perl -Te :)

        If I write a CGI or something with root rights or generally with foreign user input, it's mandatory.

        I use taint mode in any software pertaining to business, and most certainly in scripts which are not user driven, such as glue stuff for critical automation. It doesn't exempt me from looking closely at the modules I use, but it catches dangerous stuff even there.

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: When not to use taint mode
by holli (Abbot) on Jun 12, 2021 at 21:42 UTC
    Why did the Perl programmer get fired on the spot?



    holli

    You can lead your users to water, but alas, you cannot drown them.
Re: When not to use taint mode
by Anonymous Monk on Jun 12, 2021 at 19:21 UTC
    > It seems from this poll that most others don't use it either

    Hmmm... Seems to me that the poll is just saying that 3/4 don't know it.

    And 2/3 of the rest also use it.

      > Hmmm... Seems to me that the poll is just saying that 3/4 don't know it.

      true, which answers the "when not" for 75%

      More often than not 5/2% Occasionally 21/7% Never 48/16% What is taint mode? 219/75%

      But ...

      > And 2/3 of the rest also use it.

      I think you misread the 16%.

      So (almost) 2/3 of the rest is NOT using it.

      edit

      Anyway I don't think this is a good poll anyway.

      There was no option for "always"

      And if someone is not writing code dealing with untrusted input he'll rightfully say never.

      Not all of us are web-devs, a decent survey would break that down on usage patterns.

      FWIW: PM-Polls are mostly for fun, not information ...

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      the poll is just saying that 3/4 don't know it

      If they don't know what taint mode is and it isn't on my default then we can assume that they are not using it...
      Having said that, I didn't realise until I read afoken's answer that Perl will sometimes turn on taint mode without being told.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2021-09-16 22:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?