http://www.perlmonks.org?node_id=82619

I have been researching what needs to be done to get CGI scripts to run with taint checking when using ActiveState and IIS. Unfortunately, I've encountered some significant obstacles. In my opinion, ActiveState does not give security a high priority -- as you'll see below.

I've mentioned a couple of email addresses below. If you send anyone email, please be polite. If you like, feel free to CC me on the email at poec@yahoo.com

The length of this post is for two reasons:

  1. To let you know that I really have done my homework and would appreciate some serious discussion regarding alternatives.
  2. To give other monks the benefits of my research.

There's a lot of stuff here, so...

ISAPI vs. CGI

Microsoft's Internet Server API, or ISAPI, does not require a separate executable -- in this case, perl.exe. Instead, the PerlIS.dll is loaded into memory. Every time a CGI script is called, the script is fed to the DLL. This has good and bad points. The good point is that PerlIS.dll is memory-resident and does not require that perl.exe be fired up every time. This allows for a significant performance improvement over straight CGI, where perl.exe is loaded, run, and fed the script every time. The bad point: you cannot use taint checking.

If you have ever tried to run a CGI script from the command line, you've probably seen the Too late for -T error at one time or another. That's because Perl requires that the executable be started with taint mode before it tries to read in your code. Since you cannot pass switches directly to the PerlIS.dll, you cannot start it in taint mode. However, if try to associate your CGI scripts with "C:\perl\bin\perl.exe -T %s %s" to get taint mode, you sacrifice performance.* So what's one to do?

PerlEx, FastCGI, and mod_perl

PerlEx

Okay, PerlIS.dll doesn't allow taint checking. perl.exe is slow. So we need to find a reasonable alternative that allows us to preserve security. I contacted ActiveState about PerlEx, because I couldn't find any clear information regarding whether or not it allowed taint checking. Their response, on 2001-5-16:

Unfortunately, PerlEx does not currently allow you to use taint checking. However, it is being considered as a feature of the next PerlEx release, which is scheduled to occur in the couple of months.

Naturally, I gave feeback about this and I was told that it was passed on to their PerlEx development team. I won't hold my breath. If you feel as strongly about this issue as I, maybe you should let them know

FastCGI

Anyone remember FastCGI? I haven't heard much about them lately, but it appears that they are still kicking around. Their claim:

FastCGI is a language independent, scalable, open extension to CGI that provides high performance without the limitations of server specific APIs.

Here's what they have to say regarding IIS:

Netscape & Microsoft - Fast Engines used to provide FastCGI server extensions to Microsoft's IIS and Netscape's Enterprise Servers on a variety of platforms but since they were bought by Adero they are no longer available.

No longer available? I thought this meant "no longer available from FastCGI". I went over to Adero's Web site and searched, but couldn't find any information about FastCGI for IIS. I sent their sales department an email stating my needs and received the following reply on 2001-05-22:

[FastCGI] is no longer commercially available. We are only selling it to existing customers that require more licenses. If this is your situation advise me and we will see what we can do for you.

What???? This company bought an open-source product and now no longer allows it to be distributed. While I suppose that's their right, I'm pretty annoyed by this. If anyone else is wondering why they did this, feel free to ask them.

mod_perl

Of course, it's only available for Apache. This would be perfect, but the owner of our company strongly desires that we use Microsoft products as much as possible. I'm not going to get into the pros and cons of that, but it means that the one good performance option that we have that would also allow taint checking is simply not an option.

Alternatives to taint checking?

Code Reviews

One possibility is to ensure that all code that will be moved into production get a thorough code review from others who are familiar with security.

Yeah, right.

We know how hard it is to get a code review when security isn't involved. Why should anything change now? Further, some maintenance programmer going in later to make a quick fix could easily open up new holes. Code review is nice -- and should be mandatory -- but is not the best option.

Shop standards and code templates

This I think has more merit than one would imagine. Shop standards should, amongst other things, reinforce basic security concepts: untaint data, use placeholders with DBI, specify what's allowed (not what's disallowed), etc. Comprehensive shop standards and basic education on security can go a long way to closing most of the common security problems.

So what's this code template thing? When you first start a new program (you've already designed it, right?), you hit ctrl-n in your editor and a full code template pops up (good editors allow you to design your own template):

# Author: _______________ # Program: _______________ # Date: _______________ # Purpose: _______________ # Input: _______________ # Output: _______________ use warnings; use strict; # Declare globals # Get input parameters # Untaint data # Validate data

I'm not saying you should use the template above, but a basic code template can have "comment" reminders of each section of code that programmers should pay attention to. It's much less easy to forget to validate data when you keep staring at a comment telling you to do this.

But what the heck is the "Untaint data" doing there? I thought we didn't have taint checking available.

So what? We can act like we do. The program will still be more secure and if I can get taint checking in the future, I don't have a lot of code revision to do!

Weird alternatives

This is where I am definitely open for suggestions. I've tried thinking about stuff like tying an entire namespace to functions that won't allow me to use the data unless I "scrub" it. Needless to say, that's crazy and will kill the performance that I sit here and worry about.

Perhaps I should build a suite of testing tools. I seem to recall that rain.forest.puppy wrote a tool in Perl that will automatically scan sites for vulnerabilities. If it works, maybe I should grab it and scan my own stuff. Alternatively, should I buy a commercial package that will do this for me?

Convince the owner that we really do need a QA department!

Put together a quick and dirty hack that will probe for the most common issues:

  • Null bytes
  • Single quote marks in input fields (if it crashes the site, it could mean unquoted data is being sent to a database. Hmm...)
  • False credentials presented in cookies
  • Spurious parameters
  • Sidestep Javascript validation
  • etc...

Ugh. There's a lot that I could add to the above list. Maybe a quick and dirty hack isn't an option.

Where to go from here

I'm still looking for a way to deal with this. Any and all comments are appreciated. I'm still not sure what route the company will take to deal with this issue. If I had my way, we'd switch to Apache and Linux, but that's not going to happen. Until then... I'm still searching.

Cheers,
Ovid

Update: seanbo pointed out that I forgot a <readmore> tag, so I added one. Seems this post is a lot longer than I realized :)

* I also appear to have sacrificed getting my scripts to run at all. I have quite a few scripts that work fine with PerlIS.dll but die horrible deaths with mysterious error messages when run through perl.exe, but I'm still researching that.

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Replies are listed 'Best First'.
Re: Alternatives to Taint Checking?
by tinman (Curate) on May 23, 2001 at 21:19 UTC

    Ovid, compliments on a great post..I know I'll be following any discussion on this thread with great interest

    I have a few CGI scripts for the company that I work for, and I have recently come up against the same problem (I actually didn't want to install Perl on the webservers, so I took the really lazy way out and compiled the scripts into executables..), performance is an issue now, though, and both the compiled executables and conventional CGI scripts fail various load tests.. because of my employers committment to a Microsoft based server platform, I am also considering a move to ISAPI..

    I wasn't aware of a tainting issue with ISAPI, but I can see one way around it...if the production and development servers are separated, because performance is not a big issue in the development servers, run Apache for Win32 and mod_perl and/or CGI scripts, and enable tainting... if a good test suite can be built (you really do need a separate QA unit, possibly running their own webservers, if needed), and if all the obvious taint checks are passed in the development servers, then, you can "promote" the script to run on the ISAPI based production servers (even with taint checks turned off)..

    Its by no means a perfect solution, but given the restrictions which you have to work with (and these restrictions are the same ones that I work under as well), its the only way to ensure that some level of security checks are passed before a script runs in a production server...

    Might I also add that nessus is a particularly useful piece of software for running automated security checks on servers.. it can't catch everything of course, but it does probe servers for the more common types of CGI and server vulnerabilities..
    HTH

Re (tilly) 1: Alternatives to Taint Checking?
by tilly (Archbishop) on May 23, 2001 at 21:20 UTC
    One alternative. Write everything so it can easily run either as CGI or other. Run a test environment in CGI with working taint checking. Switch to a faster test environment on the way to production, resulting in losing run-time taint checks (which your code already passed).
(tye)Re: Alternatives to Taint Checking?
by tye (Sage) on May 24, 2001 at 03:29 UTC

    But in the context of taint checking w/ CGI, isn't the main point just that you should scrub your CGI parameters?? Your web server should not be set-UID to root so the security problem is that stuff from "the world" needs to be checked.

    So isn't a reasonable solution as simple as replacing the few CGI.pm methods that get data from the client with versions that require "scrubbing instructions"? I'd probably make a tiny hack to CGI.pm to prevent it from being used directly and then make a CGI::Safe where the param() method is a fatal error but safeparam() requires an extra argument that is the scrubbing instructions.

    I'd support a few formats of scrubbing instructions. You should make the most common case of requiring the parameter value to match /^\w[-\w.]*\z/ be very easy. But if a ref to a regex is provided, then apply the regex and die if it fails, return $1 if successful. If a code ref is provided, just run that code.

            - tye (but my friends call me "Tye")
Re: Alternatives to Taint Checking?
by rob_au (Abbot) on May 24, 2001 at 06:22 UTC
    An alternative which I have used before in packages that I have written that demanded taint checking for security reasons, was to use the Taint module - I used this, in combination with some code to 'unscrub' the passed parameters (as suggested by Tye) to vet parameters passed to the package module I wrote before passing the details into a banking gateway package.

    While this method doesn't give you the flexibility of having the perl interpreter die if tainted data is passed into an insecure statement, it does allow you to easily build 'taint checks' into your data in the same way - Yes, these checks could easily be done through weird alternatives for each section of code. This method with Taint.pm however, I feel is a better option, although I must admit it does take some forethought on the part of the programmer to identify insecure points of execution.

Re: Alternatives to Taint Checking?
by seanbo (Chaplain) on May 23, 2001 at 22:41 UTC
    Ovid, you obviously did your homework here. This is a very thorough and informative post. Thank you. Only one thing bothers me...it could have used a readmore tag somewhere about a third of the way up. Despite me obviously being picky, it was a great post and I appreciate you taking the time to put it all out there for us.

    seanbo
    Ahh..the odd dog is a strange beast indeed, nobody wants him, but he always seems to be there.