Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Dangerous diamonds!

by sauoq (Abbot)
on May 21, 2003 at 02:25 UTC ( #259629=note: print w/ replies, xml ) Need Help??


in reply to Dangerous diamonds!

I think this should be changed. The default behavior should be just as you, tye, and others have pointed out.

But, to put it in perspective, the problem isn't as terribly nasty as it has been made out to be in some posts here. Boil it down and it is simply a question of how much you can or should trust the source of your data. (And I think that was the real point Abigail was trying to make, even he went off on a bit of a tangent.)

In other words, it's the same old issue that pops up time and again with CGI scripts. We constantly remind people that they can't trust the data submitted to their scripts so they really should use taint checking. We educate them. Continually. The only differences in the case of Perl, the diamond operator, and shell globs are:

  1. Intuitively, it seems such a thing would be innocuous because we use shell globs all the time with other programs, and...
  2. We can usually place a higher level of trust in the names of the files we are working with than we can in input from some random websurfer.

A reasonable effort at following best practices will almost eliminate any potential danger from this infamous little "feature." There is no need for hyper-rigorous draconian super-sysadmining, which we all know is unrealistic anyway. Good habits are sufficient.

Limit file and, especially, directory permissions. Use system accounts and groups to create sandboxes and segregate users.¹ Don't run processes, particularly automated ones, with greater privileges than necessary. Look at the files in a directory before you leap at them all willy-nilly with a splat on the command line.²

These things are (or should be) second nature to experienced administrators. They are, afterall, the same measures that protect us against many far more subtle threats than a file named 'chown root:root somefile && chmod 4555 somefile|' which sits around waiting to get executed by an unsuspecting root privileged perl script foolishly making use of ARGV.

Besides, whenever (or if) this is fixed, we'll still have to educate people on the dangers of using two argument open. Afterall, perl -e 'open F, $_ and print <F> for @ARGV' is no better than using -p. (Though, admittedly, perl isn't making the decision for you in that case.)

The security implications are real, but the magnitude of the threat is actually small and completely avoidable. This behavior of perl's isn't exactly news but, as you point out, lots of experience Perl coders are unaware of it. That means two things: 1) there is room for more education and 2) it hasn't caused much of a problem over the years. I think that tye's call for a CERT advisory is a bit melodramatic.

So, in summary, yeah; I think it should be changed. It's a minor security risk and, just as damnable and maybe moreso, it doesn't work as you'd expect. As tye pointed out, -p and ilk don't play nicely with filenames that start with whitespace. (They don't like files ending with whitespace either.) That's good enough reason to change it.

¹ In another post you said:

The one-liners run as root because they need to do things that only root can do.
The one-liners couldn't do what they need to do if they were not run as root.
And THAT would be a bug.
Do you have an example? There is likely a better way of configuring things so that root doesn't have to do the task.

² Excuses like, "there are too many files in the directory to see all of them easily" don't hold up. If there are, then one shouldn't be using * anyway. There are always other choices like ls | less or a better constructed pattern to match exactly the desired files.

-sauoq
"My two cents aren't worth a dime.";


Comment on Re: Dangerous diamonds!
Re: Re: Dangerous diamonds!
by Juerd (Abbot) on May 21, 2003 at 05:43 UTC

    Do you have an example? There is likely a better way of configuring things so that root doesn't have to do the task.

    Scripts that clean up after users. System wide /tmp and per-user ~/tmp directories, for example. And scripts that md5sum some user files. Perhaps the smallish log rotator could be run as apache. Let's see, nope, Apache writes its logs as root.

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

      It is time to learn about sudo, then. Write short scripts that do exactly as much as whatever extended priveleges (root or otherwise) are necessary for, and no more, and give exactly specified users the permission to execute them under another exactly specified account without being asked for a password. Your /etc/sudoers might grow somewhat, but the result is a completely controlled environment.

      Makeshifts last the longest.

      Scripts that clean up after users. System wide /tmp and per-user ~/tmp directories, for example.

      Make /tmp owned by 'sys' or create a system user for it. You can do the same for ~/tmp directories, just make them group writable by a system group... But really, users should be left to clean up after themselves. Institute quotas if they refuse to do so. Give them access to cron so they can automate cleanup if they like. This has an added benefit; since it is their ~/tmp directory, they should choose how old files should be before they are removed.

      And scripts that md5sum some user files.

      I'm sure there is an easy solution, but its hard to say what it is without more information. Why are you doing it? Which user files? Do you really need a glob to describe them or do they have well-defined names? Is it a service to users that they can be given control of (like cleaning up their ~/tmp dirs?) Can the files in question be group readable?

      Perhaps the smallish log rotator could be run as apache. Let's see, nope, Apache writes its logs as root.

      Out of the numerous ways you can handle that one, I'll point out the easiest: make the logs directory writable only by root. You shouldn't have to do anything because that's the default anyway. Since someone would need root before creating a file with an evil filename in that directory, it would be pointless for them to do so.

      -sauoq
      "My two cents aren't worth a dime.";
      

        Do you really need a glob to describe them or do they have well-defined names?

        No. It's just laziness. I could opendir/readdir/closedir and use three-arg open. But I didn't, because I didn't know -p/-n used two-arg open.

        I'll point out the easiest: make the logs directory writable only by root.

        It already is, but one little bug in Apache could perhaps allow the names to be user-defined. After all, the logs are full of user input.

        Anyhow, it *all* boils down to laziness. I could set up ACLs, of course. It's a matter of convenience. Usually this works out just fine. Too bad this time Perl didn't DWIM.

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

Re^2: Dangerous diamonds! (races)
by tye (Cardinal) on May 21, 2003 at 21:51 UTC
    Excuses like, "there are too many files in the directory to see all of them easily" don't hold up.

    Classic security exploits often involve race conditions:

    root: hacker: # cd /user/joe # ls -a (a few normal files listed) # >'adduser x 0|' # pgrep '\b\d{3}-\d{4}\b' *

    (Where pgrep is a Perl-based 'grep' command such as this one that you might want because you like Perl regular expressions.)

    So I don't think looking at what * will expand to before you use it makes that much sense. But mostly I still consider it a very poor tool that will leak file name contents into the execution stream. That is just such a bad idea that I think most people will find such very surprising and easy to forget.

    I don't feel like I'm being dramatic in saying that this should be a CERT advisory. That something as simple as using "pgrep" as root on files whose names you don't control can run arbitrary code (as root) is a serious security risk that could easily result in security being breached somewhere.

    It is easy to come up with many different ways this could end up breaching security. So far, I haven't come up with a really plausible way that I could use this to gain privileges somewhere. But the huge number of implausible ways that are so easy to come up with convince me that this is a real risk; that someone will figure out a plausible way to use this to "break in" somewhere. It is a larger security hole than many items that have been the subject of CERT advisories.

                    - tye
      Classic security exploits often involve race conditions:

      How do you suppose user blackhat will manage to predict 1) that a root user will be using pgrep in a blackhat writable directory and 2) exactly when he should create his evil file?

      Yes, exploiting race conditions is a classic attack strategy... against processes that run with elevated privileges and which are in some way predictable. Generally, they involve doing something repeatedly in a tight loop, like creating a symlink for instance. Attempting to use this strategy against a human being does not pose a realistic threat.

      But mostly I still consider it a very poor tool that will leak file name contents into the execution stream.

      I agree that it's a misfeature. This one issue isn't enough to make me call perl² a "poor tool" though.

      That something as simple as using "pgrep" as root on files whose names you don't control can run arbitrary code (as root) is a serious security risk that could easily result in security being breached somewhere.

      It's true that there is a security risk present here, but that risk is really very small. There aren't even simple criteria by which to determine if any particular system has a security vulnerability due to this behavior. Building on your example, even if pgrep is installed it may be that the root user only uses it responsibly or not at all.

      But the huge number of implausible ways that are so easy to come up with convince me that this is a real risk; that someone will figure out a plausible way to use this to "break in" somewhere.

      Even if someone figures out how to use this behavior to "'break in' somewhere', their attack will be specific to the system they are violating. If someone were able to write an exploit based on it that would affect any significant number of machines, the chances are that it would already have been done² a dozen times over and they'd all be available on every script-kiddy site on the web. If, on the other hand, a widely distributed perl script is found to misuse two-argument open(), then CERT should issue an advisory or at least a vulnerability note about the guilty script. In fact, there are several of those already. (e.g. VU#453475, VU#181907, VU#671444, etc.)

      It is a larger security hole than many items that have been the subject of CERT advisories.

      I respectfully disagree. Most CERT advisories address specific vulnerabilities which have well-defined exploits. There have, however, been a few general advisories such as CA-1997-25: Sanitizing User-Supplied Data in CGI Scripts which address a whole class of vulnerabilities. By the way, that one mentions Perl; it says,

      "The cause of the problem is not the CGI scripting language (such as Perl and C). Rather, the problem lies in how an individual writes his or her script. In many cases, the author of the script has not sufficiently sanitized user-supplied input."
      Let's face it though, the threat of an authorized user gaining elevated privileges on a system by seeding a directory with poisoned filenames is not nearly the same risk posed by a web user being able to gain unauthorized access to a system by feeding a CGI script a poisoned query.

      I'll say again that I do think there needs to be a change. But let's keep a realistic view of the security implications. There is no cause for a panic inducing advisory. In fact, there is nothing here that should prevent a slow graceful transition from the current default behavior to something sane. That seems to be the direction things are already going. At least we have the 3-arg open() now. I advocate educating people and I agree that there hasn't been enough of that. I'll try to do my part from here on out.


      [1] Nor, for that matter would I call the -p or -n switches or the diamond operator "poor tools." They are just tools that require a little more caution... like a band saw or a blow torch.

      [2] This "feature" is not new; in fact, it's old. The problem is with two-argument open() not just that perl uses it with <>, -p, and such. Chip wrote about it here in Two-arg open() considered dangerous a year and a half ago. The 3-arg form was only introduced about a year and a half prior to that, iirc, when 5.6 came out. From perl56delta: "This is primarily useful for protecting against unintended magic behavior of the traditional two-argument form."

      -sauoq
      "My two cents aren't worth a dime.";
      

        Let me preface this by saying that most of this isn't very important. Most is arguing fine lines and grey areas and so it isn't anything for anyone to get upset about. I wanted to try to clarify a bit. Skip to the last two paragraphs if you are somehow reading this but don't care about minor details. (:

        How do you suppose user blackhat will manage to predict

        As I said, I don't have a plausible exploit handy. It was a 15-second demonstration of the race condition. Maybe he does something so low-tech as to peek over the cubicle wall.

        But I still consider "check what files are there before you use 'perl -ne ... *' as root" to be pretty poor advice. Just don't use 'perl -ne ... *' as root until the problem is fixed (and check that root isn't using any Perl tools that use <> somewhere inside).

        I can imagine the poor slob fixing his cron job to check for bad file names before running pgrep (as opposed to filtering out bad file names before feeding the filenames to pgrep or just fixing pgrep).

        I never said "Perl is a poor tool". I suppose I could have been more precise and said something awkward like... well, something awkward. If you read "it will be sad day when" and think, "Well, nothing happy will happen the entire day of when that happens"? I consider the feature of executing filenames to be a pathetic feature. But big adjectives don't make for eloquent speech.

        I guess you are right. I'm saying "CERT advisory" when I'm thinking of a broader concept that includes things like "SANS security alert".

        There is no cause for a panic inducing advisory.

        I really think "Don't use 'perl -ne ... *' as root" needs to be announced on several security alert streams. I don't think such needs to induce panic. I think it would be somewhat hard to word it so poorly that it would induce panic. *shrug*

        The problem is with two-argument open() not just that perl uses it with <>, -p, and such

        2-argument open just doesn't bother me near as much. I like to write open FH, "< $file\0" and have been doing that since Perl 4. That is every bit as safe as 3-argument open (if I am to believe the Perl 4 manuals) or the older sysopen. Sure, you can misuse 2-argument open and, as an interface design it affords such misuse and so isn't a great interface design. But I think <> goes a step beyond affording misuse, it makes it trivial to misuse and dang hard to use safely and the unsafe usage doesn't seem useful to me (as open says, the magic nature can be useful by making it easy for users to tell you to get your input from a command instead of a file).

        But none of this is that important.

        a slow graceful transition from the current default behavior to something sane. That seems to be the direction things are already going.

        I hope so. I don't see that yet.

                        - tye

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (12)
As of 2014-09-22 17:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (198 votes), past polls