Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: Dangerous diamonds!

by Abigail-II (Bishop)
on May 18, 2003 at 21:38 UTC ( [id://259019]=note: print w/replies, xml ) Need Help??


in reply to Dangerous diamonds!

The problem doesn't like in magic open. The problem lies in assuming world writeable directories are safe. Consider the following program:
foreach my $file (@ARGV) { open my $fh => ">", $file or die "Failed to open $file: $!\n"; print $fh "Buzzle\n"; close $fh or die "Failed to close $file: $!\n"; }

Or even:

foreach my $file (@ARGV) { truncate $file, 0 or die "Failed to truncate $file: $!\n"; }

which doesn't even open a file, let alone use magic open. If you call any of those programs in a world writeable directory with * as argument as root, you're open for a DoS attack. All the attacker needs to do is create a symbolic link in the directory, pointing to an important file like /etc/passwd or /vmunix, and KABOOM!.

It would very insecure to think that using 3-arg open will fix your problems.

Abigail

Replies are listed 'Best First'.
Re: Re: Dangerous diamonds!
by Juerd (Abbot) on May 18, 2003 at 22:08 UTC
    Sigh. I KNOW THAT.

    The problem doesn't like in magic open. The problem lies in assuming world writeable directories are safe.

    No.

    The problem that I am discussing is that it's using 2-arg open without me knowing it is. Now that I know it does do that, I won't make the mistake of EVER doing any -pe'something' * in something that is automated again. Too bad, since Perl really is nice as a one-liner crafting tool. Or I thought it was.

    Consider the following program:

    Blah blah. Those two examples are completely unrelated. They only happen to use @ARGV. I was *NOT* discussing the array @ARGV, but the magic filehandle that opens implicitly.

    Your examples change the files, which is by definition less secure. My concern is with scripts/one-liners that readline *ARGV without knowing it could be any mode. I'm talking about implicit open, you're talking about explicit open and explicit truncate.

    Please step into the real world and realise people make mistakes, and that people sometimes think they know how something works but do not. I thought I knew what magic ARGV did (Note again: @ARGV is not magic. I'm talking about *ARGV{IO} here, and only that.), but apparently did not.

    My search on my server, on which multiple people automate tasks using Perl one-liners, proves that I'm not the only one that opened up huge security holes by assuming -n and -p were safe (again assuming no $ARGV, no @ARGV and no $^I or ANYTHING that *changes* files).

    It would very insecure to think that using 3-arg open will fix your problems.

    Pedant. Let me rephrase: 3-arg open with "<" as its second argument would fix most of the problem that I describe. Possibly still has exploits with nullbytes and such, but at least those are real exploits, and not some stupid Perl bugfeature that can very easily be abused.

    To anyone reading my post: I acknowledge that it is a feature (after all, it's documented and sometimes useful) and not a bug. I also agree that you shouldn't assume things. But people do assume a lot and my message serves as a warning for people like me. In some IRC channels some people were quite shocked and started editing their scripts immediately.

    Sometimes I wonder why it is that in Perl world you cannot warn people or express your wishes without getting replies about that things are supposed to work the way they do, that any changes would break legacy scripts, that I should have been perfect in the first place and that worse situations are possible too.

    So, to avoid further confusion:

    • Beware: magic ARGV (implied by -p and -e) uses two-arg open and can open files in a not-read-only mode and can even execute external commands.
    • How it works now is a feature, documented in perlop.
    • I wish it were different (explicit read-only using three-arg open).
    • I'm only talking about the magic ARGV filehandle, not about $ARGV, @ARGV or its elements.

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      To anyone reading my post: I acknowledge that it is a feature (after all, it's documented and sometimes useful) and not a bug.
      I disagree. That is like saying that carrying a loaded and unlocked gun with you all the time is sometimes useful. You'll accidently shoot someone that way, likely even yourself while not even handling the gun.

      If people want to make use of the effect that this kind of "feature" achieves now, they should program the loop explicitely. How much work is it? Is it really worth the savings?

      Again, in summary: <> should only try to open existing files, and for reading only.

        Again, in summary: <> should only try to open existing files, and for reading only.

        I agree that it *should* only open files for reading. I was just acknowledging that the current handling of magic ARGV is a feature because it is documented as one.

        Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      Please step into the real world and realise people make mistakes, and that people sometimes think they know how something works but do not. I thought I knew what magic ARGV did (Note again: @ARGV is not magic. I'm talking about *ARGV{IO} here, and only that.), but apparently did not.

      Please step into the real world, where it is your responsibility to know what you are running when you are logged in as root.

      Update: tilly has pointed out to me that the interface is partly to blame whether or not this is documented behavior. I agree that it is _partly_ the blame of the interface. The other part of the blame, I believe, still lies with the user of the interface. The point is to be extremely careful when you do things as root that you do know what is going on.

      tye points out that it's nearly impossible to tell if one of some large number of modules uses the diamond operator. It is similarly difficult to tell if some portion of a C library does something stupid. This doesn't mean that C is inherently insecure, nor does it mean that Perl is. The furor has been over one-liners, which are simple enough that you CAN tell everything they are doing. Taint.pm is your friend in either case.

      I do agree it's worth fixing. I don't think it's entirely outside the responsibility of the user to be aware of shortcomings before they are fixed, though. End of update

      Christopher E. Stith
      use coffee;

        Have you ever run a Perl script as root? If so, did you read the entire source tree of modules that get included by that script to make sure not a single one of them did:

        my $data= do { local(*ARGV); @ARGV= $filename; <> };
        It is a very broken tool that takes the contents of file names and lets it leak into the execution stream. Perl usually does a better job of avoiding such stupidity than many Unix tools and so I've often replaced non-Perl tools with Perl tools thinking I was improving security.

        But now I have to add Perl to my list of things to "never trust". Why? Because it isn't reasonable for me to constantly keep track of exactly which modules might have been updated and might have decided to start using <>. Yes, in the real world, you have to make assumptions based on imperfect information and so you have to sometimes put your trust into things that you haven't recently disassembled and digested completely.

        The phrase

        know what you are running when you are logged in as root
        is good advice but is very black-and-white and very much "in a perfect world" thinking when used to disregard a serious flaw in software. "In a perfect world, you can know exactly what you are running when you are root." In the real world, you are reasonably cautious.

        Now this <> brokenness means that I can't trust the most basic of Perl code. This is not how it should be. And it is easy to fix.

        Juerd may be complaining about not having realized that <> will pass file names to the shell. I'm not. I don't care whether some people think I should have realized this or not. It is just plain stupid and broken as a design and should be changed, regardless of the existence of so-called documentation of this mis-feature.

        I'm not even convinced of the validity of the "it is documented" argument. All of the documentation I recall on the subject was sufficiently vague. For example:

        is equivalent to the following Perl-like pseudo code:     .... except that it isn't so cumbersome to say, and will actually work. It really does shift the @ARGV array and put the current filename into the $ARGV variable. [....]

        You can modify @ARGV before the first <> as long as the array ends up containing the list of filenames you really want.

        So I find it perfectly reasonable to interpret that as "very much like this code" except it expects the names of files that will be read (hence them being called "filenames" repeatedly) instead of arguments to be interpretted by open as perhaps filenames, perhaps filenames w/ open modes prepended, perhaps commands to be run, etc. since doing so would mean that the code actually works. Especially since it doesn't make any sense to have "> file" nor "| command" be interpretted by <>. You can come up with unusual situations where you want to be able to put "command |" into @ARGV, but you should have to specify your intentions.

                        - tye

        Please step into the real world, where it is your responsibility to know what you are running when you are logged in as root.

        It is indeed. But as I said before, in the post that you quoted, people make mistakes. I believe your mistake was to not read my post or to interpret it the wrong way.

        Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://259019]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-04-26 01:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found