Re: Opening a file error
by swiftone (Curate) on Jun 09, 2000 at 18:07 UTC
|
Update: At first I considered your tr// statement to mean that you would be doing full security checking, but it has (rightly) been pointed out that there are huge security concerns here that it would be wrong to ignore. Read KM's reply below
1) In this line:
if (!(open (OUT, ">$_"))) { print "Error opening file $_
for writing."; exit 0; }
Try this:
if(!open(OUT, ">$_")){
print "Error opening file $_ for writing: $!";
# $! holds the error mesg
exit 0;
}
The more tradional way to write this is:
open(OUT, ">$_") or die "Can't open $_ for writing: $!";
Since you are using this in a CGI program, it'd be a good idea to use perlfunc:warn or perlfunc:die too. (See the module CGI::Carp for http friendly die and warn functions)
But it doesn't seem to get to this point, so this isn't the source of the troubles.
2) some more information would be useful. You have the line:
print ">$_";
Does it get printed? (Note that print statements might occur but not get printed if they are in the buffer when the program gets confused. Either use warn statements, or set $|=1, which will autoflush any statements in the buffer).
| [reply] [d/l] [select] |
|
|
This reply didn't mention two other things with the original code that should be pointed out. First, you are not using -T (read perlsec and perlrun). Second, you aren't using -w or strict (perldoc strict and perlrun). You should NEVER NEVER NEVER NEVER create a file based on raw user input which you are doing. This is BAD BAD BAD. Learn now before you learn the hard way. You seem to use tr// to help make this safe, but it isn't the best way, and safer programming is better programming. Look at Untaint.pm for untainting of the input and read perlsec, twice. Also, I see no reason why you are using $_. Also, please skim this node but really pay attention to the comments I made on that node following it. It deals with file locking. You have no file locking here, and possibly do not need it, however you should take a look and familiarize yourself with it if you are using text files and not a DB.
swiftone is right about looking at CGI::Carp. It is a great tool for debugging CGI, just add this in your script:
use CGI::Carp qw(fatalsToBrowser);
and you will get more useful error messages to the browser, most of the time at least :)
Cheers,
KM | [reply] [d/l] |
|
|
Why are you using c-style comments? If these are in your code, then there's your trouble.
| [reply] |
RE: Opening a file error
by Ovid (Cardinal) on Jun 09, 2000 at 20:59 UTC
|
If you're trying to debug a CGI script, one thing you can do is run the program from the command line. If you have instatiantiated a new CGI object
$query = new CGI;
It will ask for name/value pairs and you enter them one per line such as
name=Irving
color=Blue
money=happiness
You would enter those for whatever value your script expects, if any. When you're done, or if you are not passing any name/value pairs to the script, hit control-D and the script will run. If you have a lot of name/value pairs, you can toss them into a file and use
$query = new CGI(FILENAME);
That will read the information from the file without you needing to retype it every time.
If you haven't used "new CGI" the program will run without asking for name/value pairs.
This may seem like a bit more work up front, but I find that it allows for a lot of quick and dirty debugging from the command line. You may also want to look into the Perl debugger. Once you get used to it, it's a wonderful tool.
Final note: not to be redundant, but the others are right when they say to never create a CGI script without -wT and use strict. A good source for initial information is a brief overview of Safe Scripting in Perl that can be found at perl.com. Also, on a Linux or Unix system with perl documentation installed, enter the following at the command line:
<CODE>
perldoc perlsec
</ | [reply] [d/l] [select] |
RE: Opening a file error
by rendhalver (Initiate) on Jun 09, 2000 at 18:12 UTC
|
$_=param('nameoffile');
tr/a-z//cd;
print ">$_";
if (!(open (OUT, ">$_"))) { print "Error opening file $_
for writing."; exit 0; }
why are you using $_ to store a file name anyway ??
try using a declared variable for storing the file name
that will work | [reply] |
RE: Opening a file error
by Cheburashka (Acolyte) on Jun 10, 2000 at 09:13 UTC
|
Ok, I took all your advice and tried to run it from the shell (by writing in the params manually (yyy for filename)) and the script work fine (creates the file i ask yyy.html)!!! But when I run it from http (I added the use CGI::Carp qw (fatalsToBrowser); line) it outputs the following error to http:
// start
yyy.html
Content-type: text/html
Software error:
Insecure dependency in open while running setgid at /dev/fd/6 line 63.
Please send mail to this site's webmaster for help.
//end
once again the script is:
**************************************
**************************************
#!/local/0/bin/perl
use CGI qw(:all);
use CGI::Carp qw(fatalsToBrowser);
print header;
.
..
...
$nameoffile=param('nameoffile');
#By the way when I tried to use
#$nameoffile=$query->param('nameoffile'); it returned the
#error "..param must be part of some structure..."
$myfilepath="$nameoffile".".html";
print "$myfilepath"; #good path returned to html
#http crashes here, unix prompt works fine
if (!(open (OUT, ">$myfilepath"))) { print "Error opening file $myfilepath for writing."; exit 0; }
print "end\n"; #http never gets here
**************************************
**************************************
//none of the other shell debugging hints really apply (like using $! for error) because script works great from the shell.
Any ideas what this could mean anyone?
| [reply] |
|
|
You're getting the error:
> Software error:
> Insecure dependency in open while running setgid
which means that your software is doing something good and
right. You said earlier that you weren't yet worrying about
security in your scripts... well, you should be happy that you're
getting this error, then! It means that at least you have software
looking out for your security.
Anyway, if you read perlsec, you'll find that this error is occurring
because you're using tainted data--data that's coming from a
source external to your program. This is a problem in a CGI
environment, because you don't control the input to your
script. And in fact, the example you use is a huge security
hole.
To untaint your data, you can check run it through a regular
expression that checks for safe characters, then grab the safe
characters and use those for your filename. perlsec has this
example:
if ($data =~ /^([-\@\w.]+)$/) {
$data = $1; # $data now untainted
} else {
die "Bad data in $data"; # log this somewhere
}
So you can do something similar to your $nameoffile variable.
Run it through a similar regular expression and then set it
to $1.
Read perlsec so that you write secure code.
By the way, you also said this:
> #By the way when I tried to use
> #$nameoffile=$query->param('nameoffile'); it returned the
> #error "..param must be part of some structure..."
That code tries to call the param method on the $query object.
You don't have a $query object defined, so you can't call a
method on it. Just using
param('nameoffile')
like you are should work fine.
| [reply] [d/l] [select] |
Re: Opening a file error
by rendhalver (Initiate) on Jun 09, 2000 at 19:02 UTC
|
ask me about perl, i dare you
$_=param('nameoffile');
tr/a-z//cd; print ">$_";
if (!(open (OUT, ">$_"))) { print "Error opening file $_ for writing."; exit 0; }
had a think
it could be stuffing up because you have not imported
param in the name space of your script
if not you will have to fully qualify it
ie $var = $query->param('nameoffile');
| [reply] |
Re: Opening a file error
by Anonymous Monk on Jun 09, 2000 at 21:14 UTC
|
Hello. I am the guy who posted the question. WOW, I didn't expect so many replies in such a short time...I thank you for all your advice but I would like to point out that:
1. Yes, print ">$_"; prints a perfectly good path.
2. I don't care for security so far, all I want to understand is why when I enter ,say, myfile.html in a form,
it UNDERSTANDS it, spits it out at the print ">$_"; line,
and seems to behave PERFECTLY WELL ..EXCEPT when it gets to the open file line.
Thanx for the debugging tips though, I will examine each reply very careful. I think with all that new info, It will be pretty easy to debug it. Averall I like Perl very much. Reminds me a lot of C (my favorite language of all time.)
Eugene
| [reply] |
|
|
1. Yes, print "<$_"; prints a perfectly good path.
This stumps me then. Although I'm not up on the tr// operator...what happens if you comment that out and try "safe" names (such as "aaa")?
2. I don't care for security so far, all I want to
understand is why when I enter ,say, myfile.html in a
form, it UNDERSTANDS it, spits it out at the print ">$_"; line,
and seems to behave PERFECTLY WELL ..EXCEPT when it gets to
the open file line.
Well, I'm sure KM has already given you a security rant. I'll just add that it's easier to include security from the start than it is to rewrite. That said, I understand your concerns about understanding what is going on.
Let us know what kind of warnings it generates.
Averall I like Perl
very much. Reminds me a lot of C (my favorite language of all time.)
Soon you will love perl more. (near) Equal power, much easier to program. C will always have it's place though (gotta write the perl interpreter in something :))
| [reply] |
|
|
When will you start caring about security? When you write a big hole in your code and you get hacked? Even when I paint the front door to my house, I keep a lock on it. Learn to do everything the right way, right away.
Cheers,
KM
| [reply] |