Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

request for review: file reading security

by Anonymous Monk
on Sep 05, 2004 at 08:38 UTC ( #388583=perlquestion: print w/replies, xml ) Need Help??

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


I wrote a small index file for a website, it should read the contents from html files, and print them inside of a template.

what I'm concerned with is if the actual file passing method is secure enough:

this is what I have:

my $req = $ENV{QUERY_STRING}; $req =~ s/^.*\///; $req = 'index' if -e $req; my $page = "pages/$req.html"; $page = "pages/index.html" unless -e $page;

the pages are inside a pages/ folder, and the request is such that will give me the about.html page.

do you see any security flaw with this method? like being somehow able to go back in folders and read stuff you shouldn't be reading?

thank you.

Replies are listed 'Best First'.
Re: request for review: file reading security
by cchampion (Curate) on Sep 05, 2004 at 10:45 UTC

    It isn't only the security. Your line $req = 'index' if -e $req; will make all requests invoke "index". Your code means " assign to 'index' if a file named $req exists". I am not sure what you wanted to achieve that way, but here is how I would do it.

    use strict; use warnings; my $req = $ENV{QUERY_STRING}; # limits the applicability. Only lowercase file names $req = lc $req; # remove all unwanted characters from the beginning of the string. # In this example, everything except alphanumerics # and underscore is removed. $req =~ s/^[^a-z_0-9]+//; # remove an extension, if any $req =~ s/\.html$//; # default value is the index my $page = "pages/index.html"; # if the page exists, then we use it $page = "pages/$req.html" if -e "pages/$req.html" ;

    Also, consider using CGI param instead of reading the environment.


      Your line $req = 'index' if -e $req; will make all requests invoke "index"

      no it won't.

      The QUERY_STRING should not match anything, since the filename would be composed as pages/QUERY_STRING.html That's why if it matches any file, it should roll back to a default.

Re: request for review: file reading security
by Zed_Lopez (Chaplain) on Sep 05, 2004 at 09:37 UTC

    Yeah. As written, the user could pass, e.g., ../topsecretpages/index.html and start looking at the topsecretpages directory that exists at the same level as pages. (Of course, the user would have to guess or learn the name of the directory, and it is to be hoped you don't really have top secret pages lying around under your web server's document root without any protection.)

    Updated: Like the followups say, the regexp dealt with that. Teach me to answer SoPWs in the middle of the night...

      that's why there is $req =~ s/^.*\///; which should take care of that.

        I believe your code should look for literal periods:

        $req =~ s/^\.\.\///;
        But that's still poor, because what about:
        Update: Chady is right. I retract.

        pbeckingham - typist, perishable vertebrate.
Re: request for review: file reading security
by CountZero (Bishop) on Sep 05, 2004 at 12:39 UTC
    Why not using an existing templating system? It probably has already all you try to achieve here.


    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2023-12-11 08:29 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (41 votes). Check out past polls.