in reply to Running in Terminal, but not on Server

Use CGI::param() or a similar CPAN module to parse the parameters - don't do it yourself, that's ugly and error-prone.

Second hint: don't use unfiltered query params as file names. Suppose somebody enters ../../../../etc/password as the game param - an attacker could read arbitrary files on your system.

Third hint: use strict;. Always. and use warnings;

Fourth hint: local doesn't declare variables. my does.

Last one: if you use split, don't trust that the result contains two items - check it.

BTW an empty file would explain the behaviour of your script.

Replies are listed 'Best First'.
Re^2: Running in Terminal, but not on Server
by ShaZe (Novice) on Jan 24, 2008 at 22:06 UTC

    Thanks for the hints, I will try to fix them, unfortunately, I can't use Perl/CGI modules as I don't know how to install them (Everything is on a server, no remote terminal, just a cPanel)

    For the use strict; parameter, everytime I use it, my script give me an internal error when put on the server, so I never put it :(.

    Hmm and it would have been nice if it would be that, I thought the same thing first, but there's 2 line inside, and in that case, I can trust the value of split for the opened files as they are all recorded the same way, for each line, via perl. But yeah of course, I will need to verify the one made from the browser.

    It still doesn't work, but thanks for the help, at least I will be able to make it more secure. =)

      CGI is shipped with perl since perl 5.4, which is more than ten years old - chances are that CGI.pm is already installed.

      As for the debugging, try use CGI::Carp qw(fatalsToBrowser); as your first line of code - it will print error messages to the browser. (And yes, CGI::Carp is also a core module since perl 5.4).

      If you can't even access core modules, then either find another server to work on, or chose a different language. Perl without modules really sucks, compared to other languages with modules/libs.

      And btw there is cgipan, which installs CPAN modules via CGI ;-)

        Ok, I tryed what you said, to find out that what you said was true, Carp is a core module so the fuction as worked.

        Very useful, I can now know everything that goes wrong, there's even a message that write my email to report the error message, pretty nice.

        Otherwise, I found what it is.... The file can't be found, you had 50% of the answer. This is probably because the directory that got the files is protected with chmod and maybe something else, htaccess. It's a little bit normal because it is a forum.

        But I was sure that the server could use it for itself.... as hes the owner of thoses files.... So now, I really don't know what to do... I will maybe try to play with the chmods, but I don't want to create new security hole...

        Hmm and wasn't the script suppose to tell me that it was not able to open it with the die information?..

        Well, thanks a lots for everything I leanred, I will try to see what I can do with that. There's probably a way, because the forum is also in perl, and it always create and modify files. Gotta try a few things.

        Thank!

      Aww, I almost give up, I don't understand why it doesn't want to open that file. I tryed to put it in read mode, and anyway, the folders accept to be read, but not to be written, so it should work... I also tryed to put absolute URL, or starting the path from the root. Nothing Work. The program just don't want to open it.

        If you are using open my $fh, $file or die "Can't open '$file': $!";, then you will have at least the error message, and when fighting with permissions, most likely the error message is right. Remember that your webserver may be running your program with a different user and a different "current directory" than your terminal session, so your approach of using absolute filenames is very correct.

        I guess the main problem is that your file is not readable for the webserver user. I suggest that you change the permissions to one file to be world-readable (via chmod ugo+r this_one_file.txt) and then check again, and if that still fails, slowly work your way up, making directories world-readable (via chmod ugo+rx that_directory). Making things world-readable is OK if you planned to serve all data via the internet anyway, but it's stupid if you plan to keep that data hidden, hence, be careful in what you make world readable.

Re: Running in Terminal, but not on Server
by ShaZe (Novice) on Jan 25, 2008 at 15:22 UTC
    All the folders are set to 755 (Read / Execute) and the files 666 (Read) I have tryed to put them executre but it doesn't change anything. I have looked in my forum file to see how they opened their file but it's a really really long code. I have quickly copied/pasted just to see if it could work, but it didn't change anything on the error. If you wanna see the code, (it's a sub-function, so I had to use fopen instead. It seem to modifiy the filename to destroy the security hole, put a countdown limit on the opened file, and modifiy the file locking.
    # fopen: opens a file. Allows for file locking and better error-ha +ndling. sub fopen ($$;$) { my ($pack, $file, $line) = caller; $file_open++; my ($filehandle, $filename, $usetmp) = @_; ## make life easier - spot a file that's not closed! if (($debug == 1 or ($debug == 2 && $iamadmin))) { $openfiles +.= qq~$filehandle -> $filename ~; } my ($flockCorrected, $cmdResult, $openMode, $openSig); $serveros = "$^O"; if ($serveros =~ m/Win/ && substr($filename, 1, 1) eq ":") { $filename =~ s~\\~\\\\~g; # Translate windows-style \ s +lashes to windows-style \\ escaped slashes. $filename =~ s~/~\\\\~g; # Translate unix-style / slas +hes to windows-style \\ escaped slashes. } else { $filename =~ tr~\\~/~; # Translate windows-style \ s +lashes to unix-style / slashes. } $LOCK_EX = 2; # You can probably keep this +as it is set now. $LOCK_UN = 8; # You can probably keep this +as it is set now. $LOCK_SH = 1; # You can probably keep this +as it is set now. $usetempfile = 0; # Write to a temporary file w +hen updating large files. # Check whether we want write, append, or read. $filename =~ m~\A([<>+]*)(.+)~; $openSig = $1 || ''; $filename = $2 || $filename; $openMode = $yyOpenMode{$openSig} || 0; $filename =~ s~[^/\\0-9A-Za-z#%+\,\-\ \.\:@^_]~~g; # Remove + all inappropriate characters. if ($filename =~ m~/\.\./~) { &fatal_error("cannot_open","$fil +ename. $maintxt{'609'}"); } # If the file doesn't exist, but a backup does, rename the bac +kup to the filename if (!-e $filename && -e "$filename.bak") { rename("$filename.b +ak", "$filename"); } if (-z $filename && -e "$filename.bak") { rename("$filename.ba +k", "$filename"); } $testfile = $filename; if ($use_flock == 2 && $openMode) { my $count; while ($count < 15) { if (-e $filehandle) { sleep 2; } else { last; } ++$count; } unlink($filehandle) if ($count == 15); local *LFH; CORE::open(LFH, ">$filehandle"); $yyLckFile{$filehandle} = *LFH; } if ($use_flock && $openMode == 1 && $usetmp && $usetempfile && + -e $filename) { $yyTmpFile{$filehandle} = $filename; $filename .= '.tmp'; } if ($openMode > 2) { if ($openMode == 5) { $cmdResult = CORE::open($filehandle, + "+>>$filename"); } elsif ($use_flock == 1) { if ($openMode == 4) { if (-e $filename) { # We are opening for output and file locking i +s enabled... # read-open() the file rather than write-open( +)ing it. # This is to prevent open() from clobbering th +e file before # checking if it is locked. $flockCorrected = 1; $cmdResult = CORE::open($filehandle, "+<$filen +ame"); } else { $cmdResult = CORE::open($filehandle, "+>$filen +ame"); } } else { $cmdResult = CORE::open($filehandle, "+<$filename" +); } } elsif ($openMode == 4) { $cmdResult = CORE::open($filehandle, "+>$filename"); } else { $cmdResult = CORE::open($filehandle, "+<$filename"); } } elsif ($openMode == 1 && $use_flock == 1) { if (-e $filename) { # We are opening for output and file locking is enable +d... # read-open() the file rather than write-open()ing it. # This is to prevent open() from clobbering the file b +efore # checking if it is locked. $flockCorrected = 1; $cmdResult = CORE::open($filehandle, "+<$filename"); } else { $cmdResult = CORE::open($filehandle, ">$filename"); } } elsif ($openMode == 1) { $cmdResult = CORE::open($filehandle, ">$filename"); # O +pen the file for writing } elsif ($openMode == 2) { $cmdResult = CORE::open($filehandle, ">>$filename"); # +Open the file for append } elsif ($openMode == 0) { $cmdResult = CORE::open($filehandle, $filename); # +Open the file for input } unless ($cmdResult) { return 0; } if ($flockCorrected) { # The file was read-open()ed earlier, and we have now veri +fied an exclusive lock. # We shall now clobber it. flock($filehandle, $LOCK_EX); if ($faketruncation) { CORE::open(OFH, ">$filename"); unless ($cmdResult) { return 0; } print OFH ''; CORE::close(OFH); } else { truncate(*$filehandle, 0) || &fatal_error("truncation_ +error","$filename"); } seek($filehandle, 0, 0); } elsif ($use_flock == 1) { if ($openMode) { flock($filehandle, $LOCK_EX); } else { flock($filehandle, $LOCK_SH); } } return 1; }