footpad has asked for the wisdom of the Perl Monks concerning the following question:

The apprentice ponders a great while, and then begins...

During a ChatterBox conversation today, merlyn, Fastolfe, and others were very helpful in helping me solve a problem with a script from "out there" that I was trying to retrofit to be more secure. (No, it wasn't from the Unmentionable Name or Site)

The problem was caused by a template stored in a directory underneath the directory containing the CGI script. To illustrate:

/ | +-- httpd/ | +-- cgi-bin/ + +--- script1.pl + +--- locallib/ | +--- package.pm

Please note that in the above "diagram," cgi-bin/ is outside of the document tree and has its permissions set to 644.

During the conversation, merlyn warned me that storing a library in a relative path was dangerous and that it was best to separate libraries from executables. I'm trying to figure out the best way to incorporate this advice.

In following up with the other monks via ChatterBox, the following seemed to be more acceptable:

/ | +-- httpd/ | +-- cgi-bin/ | | | +--- script1.pl | +-- locallib/ | +--- package.pm

With this in mind, here are my questions:

  1. Is the above layout in fact an effective way to be more secure?

  2. Assuming that script1.pl, cgi-bin/ and locallib/ would have permissions of 644, why is this more secure? (Both locallib/ and cgi-bin/ are outside of the document tree.)

  3. Where do you put additional scripts that are used by script1.pl and that are called from other HTML forms? For example, I have a config.pl that I can call from a form in a private area using basic authentication. (config.pl set variable values and script1.pl calls it.)

  4. Would it be better for me to retool things so that config.pl resides in locallib/ and create a script2.pl to call it, e.g. store the variable definitions in locallib/?

  5. Finally, is use './locallib' as risky as placing './locallib' in PATH when tainting is enabled?

    Assuming that it is, would someone be kind enough to expand on how someone could exploit that risk or point me to a link where I can find such an explanation?

I ask this because I commonly use relative directories for data, libraries local to the script in question, configuration files, and other dependencies, save CPAN modules (which are installed into the proper locations). I have found this a useful technique for portability between machines and servers.

Given the advice, I shouldn't be doing this, so I'm trying to find an alternative that is more secure while understanding the risks and the associated exploits. Thanks in advance for any advice and illumination.

(For the record, I've looked in the faqs (perl's and LS's Web Security), the man pages, and Super Search, but all I find are notes about the risk, not examples of how it couple be exploited or used properly.)

Replies are listed 'Best First'.
Re: Understanding Secure File Organization
by Fastolfe (Vicar) on Oct 27, 2000 at 21:23 UTC
    A few of my own comments. These probably won't be all-inclusive with any potential issues you may face, but just what's on the top of my head:
    1. In my opinion, yes. The only things you should place in or under cgi-bin are items you want the casual browser to be able to execute. Modules do not fit this category, and the casual user may attempt to execute one as a CGI script, causing potentially unexpected things to happen.
    2. /cgi-bin/ in a way is not outside your document tree. True, they won't be able to hit it and retrieve the contents of the files, but an attempt to execute it may be made. More on this in a bit.
    3. I'm not quite sure I understand. You have scripts that are called from other scripts (e.g. via system) and are independently called as normal CGI scripts? I guess you don't have much of a choice but to put them in your cgi-bin directory then...? Unless:
    4. Unless config.pl is something that you expect to be run as a CGI script independently, it should probably be placed someplace where it can't be run as such. A local "library" directory seems optimum.
    5. Are you talking about @INC or $ENV{PATH}? Your PATH environment variable only affects what items will be run via your system or qx// statements, when the shell has to examine the path to see if it can find the binary you're talking about. Generally, with 'secure' programs, you want to set your PATH explicitely to something sane (like "/bin:/usr/bin") and when you do any system/qx// calls, do so using absolute path names so the shell doesn't have to go hunting. If you're talking about @INC, you should probably specify an absolute path name. What if you move your script later to a subdirectory of cgi-bin? You'll have to re-tool your scripts to point to a different relative path. Just give it an absolute path to, say, /httpd/locallib in the first place and you'll be fine.
    In addition, data files need to be kept out of your executable/retrievable space (in, say, your locallib directory), especially in cases where the user can provide a filename for a specific data file (which, presumably, you'd untaint with /(\w+)/ or similar).
Re: Understanding Secure File Organization
by mirod (Canon) on Oct 27, 2000 at 20:54 UTC

    I ask this because I commonly use relative directories for data, libraries local to the script in question, configuration files, and other dependencies, save CPAN modules (which are installed into the proper locations). I have found this a useful technique for portability between machines and servers.

    Why don't you just use h2xs on your modules, create a proper distribution, maybe even some tests, and install them just the way you would install a CPAN module?

    Of course you need root access for that, just as if you wanted to install CPAN modules

    Or is there a security risk there too?

      Mirod,

      Primarily because this is an application and package.pm contains stuff reused between multiple applications, not sites.

      When I mention portability, it's between development machines, test servers, and (eventually) the final production server.