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

Today I was checking some code running perl -c when it core dumped on me. Upon investigation the culprit was a buggy DESTROY subroutine well outside of any BEGIN or CHECK block that I could see.

That got me thinking. What particularly concerned me was that this bit of buggy code was making system calls - nothing huge in this particular case, but it got me thinking about what else could have been in that routine. I think most people consider syntax checking a "safe" operation, but if anything can be done and anything can be invoked indirectly from within a BEGIN or CHECK block, that isn't quite true? is it?

So my question (ok questions) are:

Many thanks in advance, beth

  • Comment on What restrictions are there on code execution when running perl in syntax check mode?
  • Download Code

Replies are listed 'Best First'.
Re: What restrictions are there on code execution when running perl in syntax check mode?
by moritz (Cardinal) on Feb 03, 2009 at 19:34 UTC
    use happens at compile time, so any code in external modules actually runs in syntax check mode.

    Taint mode "behaves", as you can easily find out yourself

    $ perl -Tce 'BEGIN { system <> }' echo foo Insecure $ENV{PATH} while running with -T switch at -e line 1, <> line + 1. BEGIN failed--compilation aborted at -e line 1, <> line 1.

    perl -c script.pl is not safer than running perl script.pl if script.pl is malicious. Just the chances of accidental "bad" code are smaller.

    (Update: a few wording improvements)

    Second update: constant folding also happens at compile time, but that's hardly unsafe.

Re: What restrictions are there on code execution when running perl in syntax check mode?
by ikegami (Patriarch) on Feb 03, 2009 at 19:42 UTC

    What code other than the BEGIN {} and CHECK {} blocks get executed

    In Perl 5.10, add UNITCHECK.

    Keep in mind that use has an implicit BEGIN.

    Other language elements have compile-time effects (e.g. prototypes affect parsing, symbol names vivify entries in the symbol table), but I can't think of any other that will run code.

    and under what conditions?

    Unconditionally.

    What restrictions are there on the kinds of code executed during the syntax check mode?

    None.

    How does taint mode behave?

    Normally.

    $ perl -c -Te'BEGIN { system "/bin/ls" }' Insecure $ENV{PATH} while running with -T switch at -e line 1. BEGIN failed--compilation aborted at -e line 1. $ perl -c -Te'BEGIN { $ENV{PATH}=""; system "/bin/ls" }' bin cdrom etc ... -e syntax OK

    And if there are none, e.g. anything can be called, is this safe?

    No more or less safe than calling it without -c.

    What precautions do people use to make sure that code (especially someone else's code) is safe to syntax check?

    Safe might help, but that's just a start.

    Update: I meant to mention PPI. It might be a suitable alternative.

Re: What restrictions are there on code execution when running perl in syntax check mode? (-cT scan)
by tye (Sage) on Feb 03, 2009 at 21:18 UTC
Re: What restrictions are there on code execution when running perl in syntax check mode?
by JavaFan (Canon) on Feb 04, 2009 at 10:20 UTC
    And if there are none, e.g. anything can be called, is this safe? What precautions do people use to make sure that code (especially someone else's code) is safe to syntax check?
    One should realize, due to the nature of Perl, that you in general you cannot do a syntax check and get a useful answer without executing code. And you cannot determine whether you can do a useful syntax check without running code.

    Having said that, code I either consider safe, or not safe. If I don't consider it safe, I don't care whether it has syntax errors or not. It's unsafe. I don't want to run it. Period. If code is "safe", it's not more (or less) safe to check its syntax.

      You make a good point, but I don't think the safety problem is reducible to "If I don't think its safe...". Just scan the web for all the people who innocently rooted themselves because they had a typo in an rm command and a foolish OS distro that didn't no-op rm / by default.

      While it is true that, by nature, Perl sometimes needs to be executed to be syntax checked, that does not necessarily preclude the use of sand-boxing techniques. For instance, a call that writes to files through a Perl library isn't (usually) needed to evaluate code further down the line. Couldn't the perl syntax checker have been/be designed to monitor certain system calls and no-op them unless a flag was explicitly set to do otherwise?

      Best, beth

        The answer is to run untrusted code under a user account that has no priviledges. None, zero, zip!

        Then, as each requirement of the code to do things that require priviledges fail, you'll get an error message and line number telling what it was trying to do and where. You can then decide on a case by case basis whether to enable the account for that purpose or not.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        You make a good point, but I don't think the safety problem is reducible to "If I don't think its safe...". Just scan the web for all the people who innocently rooted themselves because they had a typo in an rm command and a foolish OS distro that didn't no-op rm / by default.
        I don't understand what typos have to do with it. You can make a typo on the command line as well. Furthermore, such typos aren't detected by syntax checks anyway.

        Also, with "if you think it's safe/not safe" means "would you run this code or not?". If you don't want to run it, for whatever reason, who cares it has syntax errors. If you've already decided that you want to run it, that doing a syntax check isn't more harmful.

        Couldn't the perl syntax checker have been/be designed to monitor certain system calls and no-op them unless a flag was explicitly set to do otherwise?
        Maybe. But fact it is, it doesn't. In fact, the syntax checker isn't anything special. What we call "the syntax checker" is the -c option. What -c does is to not run the program after it was compiled. There's no separate "check the syntax" part in perl. But you may tinker with the Safe module, and compile the code you worry about in the sandbox provided by the Safe module.

        Note however, that for whatever action you want to prevent, I can design a piece of code that cannot be compiled, unless that action is allowed.

        Actually I think it comes down to what is safe or not, to me what is safe is code I have read through and understand, the typo's are I think outside of what the safe issue is about. Either you have code checks and you read through and follow the flow and understand what it is doing, and have a typo somewhere that can cause unintended behavior.

        Or you end up with code that you have no idea what it is doing and it is generating behavior you do not want, and may be entirely unsecure in many respects.

        Don't confuse security and proper coding, which I think is what is happening here.