OSCON 2008: Perl Security

After lunch, I wandered over to Portland 255 with Brad and Al for the Perl Security tutorial, presented by Paul Fenwick. Straight away I can tell that he’s going to be a lively and entertaining presenter. His slides go by quickly, as they are merely short counterpoints to his commentary. His commentary, which is also very quick and slightly witty. I don’t expect to have any trouble paying attention. If anything, I’m worried that I’ll fail to pay attention to my writing and, of course, to the #oscon IRC channel.

“A computer is secure if you can depend on it and its software to behave as you expect.”
—Simson Garfinkel and Gene Spafford in Practical UNIX & Internet Security

In a nutshell, that’s what security is. If a computer behaves as expected, it is secure. That is, unless it’s expected to be insecure, I suppose. I’m not sure I’d enjoy that situation, so I’ll assume the assumption of expected behavior is both expected and secure.

Most security boils down to common sense. Unfortunately, this mythical state of being is far less common than its name would imply. Sad, but true. People are often lazy or distracted, and these usually lead to really stupid mistakes.

There is a key acronym when thinking about security: CIA. No, not that CIA. Yes, I thought so, too, at first. What it really means is, Confidentiality, Integrity, and Accessibility. Confidentiality, because information will not remain secure if it does not remain confidential. Integrity, because information must remain known and trusted to remain secure. Accessibility, because denial of access to information may result in insecurity. I may not have done justice to this acronym, because the tutorial moved on quickly after this point. I’m sure there are web sites dedicated to security that can better define the term.

Perhaps the most important piece of advice for the unwitting Perl programmer is to always perform data validation. Never, ever trust input, regardless of where it came from. Fortunately, Perl provides Taint Mode, which forces the program to mistrust input.

Paul shared with us a variety of examples to demonstrate why input should not be trusted, as well as a number of examples of how to properly untaint data. As with anything, it’s easy to become lazy when untainting data, which can sometimes be as bad as not using Taint Mode at all.

The tutorial continued into what is essentially a list of best practices to follow when programming securely with files.

  • Do: Use the three argument version of open(), to prevent attacks using file names with magic characters in them.
  • Do: Use sysopen() instead of open(), which provides ways to avoid overwriting a file, thus helping to prevent symlink attacks often as a result of race conditions.

The common attack vector in so many of the examples given so far has been via file names. Wouldn’t it be great if we could write programs without file names at all? Well, when working in a Unix-like environment, we can. Perl has the ability to use anonymous files by passing undef as the third argument to open(). He was even kind enough to provide us with a way of passing these anonymous file handles to child processes, by disabling the close-on-exec flag prior to calling system(). Sorry, the slide went by too quickly for me to transcribe the method. It, along with all the other examples, are available online.

Calling system() and using backticks make Paul really, really angry. Why? Because doing it right is hard. In fact, just correctly checking the result in $? requires 10 lines of code, according to the documentation for system() in the perlfunc manual page. So, 10 lines just to verify that a single line of code executed successfully.

I briefly became distracted by news of a fire back home. However, what I was able to get is that Paul has written a module, IPC::System::Simple, which, as the name implies, makes the process of calling system commands quite simple.

After the mid-afternoon break, we ventured into setuid and setgid programs. Perl provides ways to determine who is really running the program ($<, $() and who is effectively running the program ($>, $)). Perl is, however, ignorant of the saved UID, which is the third UID in Unix, along with real and effective. Unfortunately, the standard for setuid scripts is confusing and implemented differently on various systems, so don’t use it. Really.

Even worse, the $< and $> variables are cached by Perl, so they may lie to the program, especially when using the setresuid() system call to properly drop privileges, as recommended. Fortunately, another useful module from Paul, Proc::UID provides a solution to this caching problem.

Now we move into DBI security. SQL injection attacks are very similar to the file name or shell attacks covered previously. Any database programmer worth his salt should be aware of the hazards of composing SQL, so I won’t go into the examples here. Programmers should, of course, use placeholders if they’re available. The DBI module itself provides its own Taint Mode, both for input and output, adding all the benefits of Perl Taint Mode to database interface code. Even better, it can be controlled on a per-statement basis.

All of this careful taint checking we’ve done and Perl may end up sabotaging us anyway. When presented with files on the command line, Perl is happy to just open them using the simplistic, dangerous, single argument open() call. Typically, this is done when using the <> operator in a while loop. Also, everyone forgets to use Taint Mode in cron jobs. Don’t do that. Really.

Because Perl is written in C, the null byte becomes very interesting. While it is a perfectly valid character in Perl strings, it marks the end of a C string. In most circumstances, this is not a problem. However, it can mean bad things when making systems calls, which are written in C. Normally, at a terminal, null bytes don’t occur in user input, unless that input comes from the Web. Null bytes can be trivially represented by the %00 escape sequence.

I need to go through the list of Paul’s modules, since they appear to be ideal for the type of programming I tend to do, as an IT developer. In fact, he’d like to see some Solaris patches for Proc::UID, so I can probably help him with that.

I noticed during the tutorial that Paul must read the Fail Blog and I Can Has Cheezburger, or at least knows someone who does. Quite a few of the images that have appeared on his slides have graced the pages of those web sites.

As an added bonus, the tutorial ended 40 minutes early, and Paul had bonus material. What a guy.

The tutorial, and with it the day, is now over. It’s time for dinner, then maybe a BOF session or maybe just a trip to a pub.

[tags]oscon, oscon08, perl, security[/tags]

4 thoughts on “OSCON 2008: Perl Security

  1. Pingback: OSCON 2008: Perl Security, by Paul Fenwick :: canspice.org

  2. Actually, security is always relative to a policy, an operational environment, and threats. If your policy (“expectations”) are open for the environment, then it is what you expected.

    Yeah, I know that isn’t very precise, but we didn’t want to go with the precise definition that involved state spaces and transitions and so on. :-)

  3. Pingback: sirhc.us maxim.us » OSCON 2008: An Illustrated History of Failure

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>