|Keep It Simple, Stupid|
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 email@example.com
The length of this post is for two reasons:
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
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
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.
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?
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.
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):
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!
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:
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.
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.