我的CGI程序如何访问不可浏览的文件?

时间:2010-03-16 01:46:43

标签: perl cgi

我想知道是否可以读取位于名为的目录中的文本文件 “/ home / user中/文件”

我想从我的cgi-bin中读取它,它位于/ home / user / cgi-bi / 以下是我的代码,

#!/usr/bin/perl
use strict;
use CGI;


#Virtual Directory
#Steffan Harris

eval
{


use constant PASSWORD => 'perl';
use constant UPLOAD_DIR => '/home/sharris2/files';

sub mapToFile
{
   print chdir UPLOAD_DIR;

}

#This function will list all files in a directory.
sub  listDirectoryFiles
{
    chdir UPLOAD_DIR;

    my @files = <*>;

    mapToFile;
    print<<LIST;
    <h2>Current Files</h2>
      <ul>
LIST
     if(!$files[0])
     {
     print" </ul>\n<em>No files in directory</em>";
     }

    foreach(@files)
    {


    print"      <li>$_</li>";

    }
    print "     </ul>\n";


}
#This function generates a 404 Not Found error
sub generate404
{

print<<RESPONSE;
Status: 404 Not Found
Content-Type: text/html


      <html>
          <head><title>404 Not Found</title></head>
      <body>
        <p>
          <h1>404 - Not Found</h1>
        </p>
        The requested URL <b>$ENV{"HTTP_HOST"}$ENV{"REQUEST_URI"}</b> was not found on the server.
      </body>
      </html>


RESPONSE
exit;

}
#This function checks the path info to see if it matches a file in the UPLOAD_DIR directory, If it does not, then it returns a 404 error
sub checkExsistence
{

    if($ENV{"PATH_INFO"})
    {


    chdir UPLOAD_DIR;

    my @files = <*>;

    if(!$files[0] and $ENV{"PATH_INFO"} eq "/")
    {
        return;
    }


    foreach(@files)
    {


        if($ENV{"PATH_INFO"} eq "/".$_ || $ENV{"PATH_INFO"} eq "/")
        {
        print "yes";
        return;
        }


    }


    generate404;

    }


}

sub checkPassword
{
    my ($password, $cgi);
    $cgi = new CGI;

    $password = $cgi->param('passwd');

    unless($password eq PASSWORD)
    {

    print<<RESPONSE;
Status: 200 OK
Content-Type: text/html

     <html>
       <head>
         <title>Incorrect Password</title>
       </head>
       <body>
         <h1>Invalid password entered.</h1>
     <h3><a href="/~sharris2/cgi-bin/files/">Go Back</a></h3>
       </body>


RESPONSE

    exit;

    }

}


sub upLoadFile
{
    checkPassword;
    my ($uploadfile, $cgi);
    $cgi = new CGI;
    $uploadfile = $cgi->upload('uploadfile');


    chdir UPLOAD_DIR;

    $uploadfile
    or die "Did not receive a file to upload";

    open my $FILE, '>', UPLOAD_DIR."/$uploadfile" or
    die "$!";


    while(<$uploadfile>)
    {
    print $FILE $_;
    }

}

#Start of main  part of program

my $cgi = new CGI;

if(!$ENV{"PATH_INFO"})
{
    print $cgi->redirect('/~sharris2/cgi-bin/files/');
}

checkExsistence;

if($ENV{"REQUEST_METHOD"} eq "POST")
{

    upLoadFile;

}

print <<"HEADERS";
Status: 200 OK
Content-Type: text/html

HEADERS
    print <<"HTML";
<html>
    <head>
       <title>Virtual Directory</title> 
    </head>
    <body>

HTML

    listDirectoryFiles;

  print<<HTML;
       <h2>Upload a new file</h2>
      <form method = "POST" enctype = "multipart/form-data" action = "/~sharris2/cgi-bin/files/" />


          File:<input type = "file" name="uploadfile"/>



             <p>Password:
              <input type = "password" name ="passwd"/></p>
             <p><input type = "submit" value= "Submit File" /></p>


       </form>

    </body>


</html>

HTML



};

4 个答案:

答案 0 :(得分:1)

您的脚本可以读取Web服务器有权访问的任何文件,前提是SELinux和grsec等高阶安全框架不会干扰。

答案 1 :(得分:1)

始终检查chdir的状态:

chdir SOME_DIR || die "chdir failed: $!";

请记住,当您的CGI脚本死亡时,错误将进入Web服务器错误日志 - 而不是Web浏览器。

答案 2 :(得分:1)

没有必要chdir,你可能也不想真的想这样做。只是尝试打开目录。如果无法打开目录,请记录错误消息,以便了解发生的情况。请记住,您尝试访问的任何内容(包括包含目录)都必须具有相应的权限,以便让Web服务器用户执行您尝试执行的任何操作。

  sub  listDirectoryFiles
      {
      my( $dir ) = @_;

      unless( opendir my $dh, $dir )
           {
           warn "Could not open directory [$dir]: $!";
           return;
           }

      # filter "hidden" files with the map          
      my @files = map { ! /^\./ } readdir( $dh );
      ...
      }

另请记住,在您创建的任何子例程中,您都希望限制其副作用。不要依赖全局数据,也不要改变全局状态。当你控制这些事情时,你将更容易管理你的程序。

答案 3 :(得分:0)

您可能需要确保Web服务器可以读取您的文件。请注意,使用此方法,在服务器上拥有帐户的任何人都可以读取文件。 (但不是任何人只是通过网络访问)。尝试(在shell中):

chown a+r <file you want the web server to be able to read>

Web服务器还需要对您的目录执行权限(在其上键入+ x)才能访问其内容。

如果您没有shell访问您的东西,您可能必须使用任何接口来使这些东西可读。您的系统可能已设置为不允许您执行此操作。

一种可能的安全替代方法是内联脚本中的文件(或脚本调用的其他脚本)。 Web服务器不会提供脚本文本,因此您仍然可以保护内容。