Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

writting new files in perl

by Anonymous Monk
on Jul 26, 2000 at 02:26 UTC ( [id://24367]=perlquestion: print w/replies, xml ) Need Help??

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

hello, i'm trying to write a commercial cgi script to distribute to whoeer wants it :) and am coming to the problem that perl isn't allowed to write a new file in the same directory as the script is in (or any directory for that matter)

is there any simple (well perl way) to have enable perl to write a file if its not already there.

i'm getting permission denied errors when trying to do this on some servers, either writing text files, binary files or DB Files using the DB_FILE library.

any ideas anyone?

Replies are listed 'Best First'.
Re: writting new files in perl
by tye (Sage) on Jul 26, 2000 at 19:28 UTC

    I would think there would be a FAQ on how to give your CGIs access to write local files while minimizing security risks. But The Idiot's CGI Guide didn't mention this and pointed to The WWW Security FAQ, which also didn't mention it (that I could see).

    So here are some things I consider important:

    • Pick a specific directory where your CGI will write files.
    • Don't allow this directory or files in it to be served. You can do this any of the following ways, though only some of these will also satisfy the other criteria, depending on your environment.
      • Locate the directory outside of the document tree. If your web server chroot()s, then you'll need a directory under the chroot() location but outside the document tree.
      • Configure the web server to not serve that directory. Don't rely on this method alone.
      • Protect the directory from the web server. If your CGI runs in a wrapper that changes the UID that it runs under, then configure the directory so that it is readable but not executable to your CGI UID and is neither readable nor executable to the web server (nor the world).
      • Hide the directory from the web server. This is a last resort, but is a nice small layer of extra security when used with one or two of the previous methods. Find a directory, "the parent", that has a default file (such as index.html). Deny the web server execute access to the directory (but you must give it read access). Create a subdirectory with an obscure name, "the sub", in the parent. Give the web server read but no execute access to the sub. Now the web server can access the sub and files in it, but only if an attacker can guess the name of the sub and the name of the file. Not much security, but it is better than giving the attacker write access to the directory that your script is in.
    • Give your CGI and only your CGI write access (and read access but no execute access) to the directory. Note that this prevents your CGI from being able to list what files are currently in that directory. You can test for the existance of a specific file. If your CGI runs as "nobody", then I'd just abandon the whole idea and find another server since "nobody" can only write to a directory if the world can write to it.
    • Don't trust the data you read from this directory. Turning on Perl taint checks will help you remember this. Just because your CGI never writes "rm -f /" to any of these files, don't run $l=<FILE>;system($l);.

    If, like many of us, asking questions of your web server administrator is difficult, you can figure out a lot about your server configuration with some experiments. Let's assume that your user name is "joe", the root of the web tree or subtree that you have control over is "~/webroot", it is served as "http:://www.x.com/~joe", your CGIs go in "~/webroot/cgi-bin", and they are served as "http://www.x.com/cgi-bin/cgiwrap/joe/script.pl".

    cd ~/webroot chmod u=rwx,go=rx . mkdir test cd test chmod u=rwx,go=r . echo "<html><body>Nothing here.</body></html>" >index.html chmod ugo=r index.html mkdir hades chmod u=rw,go=r hades cd .. mkdir cgi-bin cd cgi-bin chmod u=rwx,go=rx .

    Now you can put test scripts in your cgi-bin directory and figure out if your server chroot()s, what UID your CGIs run under, etc.

    print "Content-type: text/html\r\n\r\n<HTML><BODY><PRE>\n"; print "$< $> $( $) $^X $] $0\n"; print join(":",getpwuid($<)),"\n"; print "$ENV{PATH}\n"; print `/bin/pwd`; # Not for Win32 #OR# print Win32::getcwd(),"\n"; # For Win32 print "</PRE></BODY></HTML>\n"; exit(0);

    Then you can try creating files:

    print "Content-type: text/html\r\n\r\n<HTML><BODY><PRE>\n"; if( ! chdir("~joe/webroot") ) { print "Can't chdir to ~joe/webroot: $!\n"; } elsif( ! open(TEST,"> hades/emptytest",0777) ) { print "Can't create emptytest: $!\n"; } else { close(TEST); } print "</PRE></BODY></HTML>\n"; exit(0);

    Once you get files created, check the ownership and permissions on the created files to double check how your CGIs are being run, for example, what umask is set.

    If you don't have shell access, then chmod via FTP will probably have to be run as quote site chmod (use quote help to check this).

Re: writting new files in perl
by merlyn (Sage) on Jul 26, 2000 at 02:38 UTC
    It's not Perl. It's the OS. You haven't told us enough info to know why it's not creating. Did you use or die "...: $!"? if so, what's the error text?

    -- Randal L. Schwartz, Perl hacker

Re: writting new files in perl
by target (Beadle) on Jul 26, 2000 at 03:29 UTC
    Although it will vary widely from OS to OS and server to server, I would guess that the script is executing as user nobody (on UNIX/Linux hosts anyway)and the System Administrator doesn't allow that uid to create files. So the Sys. Admin. of each host will have to contacted to find out if/where you can create the file. There are several other options for file creation under UNIX style OS's, but unfortunately all will involve contacting the administrator to change permissions and/or setuid values. Hope this helps and as always, this is just my opinion I could easily be, and probably am wrong.
Re: writting new files in perl
by tiny (Beadle) on Jul 26, 2000 at 06:48 UTC
    If the script is in your own home directory, make sure 'other' write permissions are set so that the webserver user (usually nobody) can create files there. Try chmod o+w directory

    If that doesn't work, follow target's advice!
RE: writting new files in perl
by Nimster (Sexton) on Jul 26, 2000 at 09:58 UTC
    Perl *does* actually right a new file when you do
    open (WHATEVER, ">filename");
    But you are probably just denied there, so check with the admin if you have write access to that dir.

    -Nimster
    Freelance writer for GameSpy industries LTD. (www.gamespy.com)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2024-03-29 05:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found