Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Problems with opendir in CGI

by ogxela (Novice)
on Mar 29, 2004 at 23:12 UTC ( #340790=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to read the contents of a directory in a CGI script, like so:
$reportsDir =~ s#\s#\\\ #g; #escape whitespace in the path $reportsDir = "/storage/$reportsDir"; opendir(REPORTDIR, "$reportsDir") or &error("Couldn't open $reportsDir +: $!"); my @logFiles = grep /csv$/, readdir REPORTDIR; closedir REPORTDIR;
This gives back a "no such file or directory" error when I run it as a CGI, but when I run it from the command line, it's fine. I've checked the permissions on the directory in question -- they're fine. Does anyone know what might be happening here?
| Alex Gottschalk Unix Systems Admin | | <> Drink java, code Perl! |

Replies are listed 'Best First'.
Re: Problems with opendir in CGI
by Vautrin (Hermit) on Mar 29, 2004 at 23:32 UTC

    You should look at the configuration of Apache (or whatever you're using). Chrooting apache into a loopback filesystem would mean that a CGI script could never "see" any file outside your cgi directory. Try creating a symbolic link to the directory in your CGI directory, and change /storage to ./storage. Also, if your web server is running with user / group of nobody (which it should be for security), it may not have permission for /storage.

    Want to support the EFF and FSF by buying cool stuff? Click here.
      Well, I've narrowed it down to a problem with the whitespace in the directory name. I renamed one of the directories that I'm trying to open with no whitespace and the CGI works fine. The "not found" error only happens on directories with whitespace in the path, which says to me that s/(\s)/\\$1/g isn't cutting it. Any suggestions?

        Don't use whitespace in dir names? Seriously. Although in theory you can escape it with \\ each time you interpolate you 'lose' one level of escape. Why not make your life easy?.

        BTW you need some decent error checking on the supplied path. ..\..\WINNT\cmd.exe or ..\..\etc\passwd anyone? There are all manner of variations on this theme. Have a look at the Webserver error logs for the 404 not found with .. %5d and friends. I suggest:

        my $full_path = '/some/path' my $cgi_path = s/\W//g; my $safe_path = "$full_path/$cgi_path";

        ie only allow the final part of the path to be passed so you can remove anything non alphanumeric. If you need more path to be passed pass it as alphanumeric fragments and build the path safely. You ARE NOT SAFE trying to remove ../ as there are 101 ways to express this ie the %5D hacks that even complex regexes will miss. You need to know exactly how the shell deals with escape chars in the path to know what will happen.



        So long as you're only passing things directly to perl builtins (i.e. you're not calling something externally using system()) spaces shouldn't need to be escaped and if you try and do so you'll cause yourself problems (as you've found out).

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://340790]
Approved by Vautrin
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2022-05-20 18:01 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (75 votes). Check out past polls.