-2

I have an error with perl while trying to CREATE a file called .envfile in the root dir / (only for UNIX). Permission denied, which is understood. But, is there a way to write this file? I need to do it without any modules, just with a built-in functions. I expect for using chmod, but... honestly, have no idea of how to implement it in the same thread SAFELY.

I need this file to write in it my own ENVs for my software (as it is a big project with many dirs and needs to operate with many own ENVs).

Trying simple:

my $filename = '.envfile';

open FH, '>', $filename or die $!;

print FH "some data\n";

close(FH);

Apache says: Permission denied at /var/www/cgi-bin/env.cgi line 41.

Any help appreciated! Thanks!

Arsenii
  • 655
  • 1
  • 8
  • 20

3 Answers3

2

Create the file 'by hand' and set it's owner to the owner of the apache process, e.g.:

sudo touch /.envfile
sudo chown www-data:www-data /.envfile
sudo chmod u+rw /.envfile
nsilent22
  • 2,763
  • 10
  • 14
  • Thanks, but.. hm... This is not what I am looking for... I know how to create a file manually..)) What I need is to create it, using ONLY PERL. – Arsenii Jul 18 '15 at 18:16
  • 4
    You won't "skip" over the privileges. If it were possible, it would be a HUGE security flaw. Another thing that comes to my mind is to create a simple "wrapper" program that writes from stdin to /.envfile, give it suid root privileges and run it from your perl script. – nsilent22 Jul 18 '15 at 18:22
  • Yepp! Ok, when we install, say, Perl, this program AUTOMATICALLY creates ENVs in the system, as we run the installation script from $ sudo. The question is: is it possible to make a run with $ sudo param FROM WITHIN the script? – Arsenii Jul 18 '15 at 18:25
  • Well, it should be possible IF the sudo is properly configured (e.g. won't prompt for the password). – nsilent22 Jul 18 '15 at 18:29
  • well, is it possible, if we prompt a user to type in the sudo password and send it in the request within the thread? – Arsenii Jul 18 '15 at 18:38
  • 3
    With -S parameter sudo reads password from stdin, so you can do it. But I think solution with wrapper with u+s privilege is better, because sudo called from apache process requires that apache's process owner is allowed to use sudo, which most likely is not true. – nsilent22 Jul 18 '15 at 18:43
2

If I understand the question correctly, it appears that you also control the software which will ultimately read the file you're trying to create. Is that accurate? If so, change the program to get its environment from somewhere else. Where else? Preferably a new directory, so that you can make it writable by your web server without affecting anything else. I'd probably use /etc/myprogram (because /etc is the standard place for configuration files) or /var/local/myprogram (because /var is the standard place for persistent data files). But not an existing directory which is and should remain writable solely by root.

Short of exploiting a security flaw, Perl does not allow you to sidestep filesystem security (permissions). And that is a Good Thing. If it were allowed, it would mean that anyone who finds an exploit in your Perl code could then change any file on your computer, potentially replacing it with the most malicious code ever written.

Thus, the only way that your Perl can create a file in / is if it runs as root or uses su/suid to run some other program as root. And you really, really, really do not want CGI scripts or web applications running as root because, unless you do everything absolutely perfectly in your code, and there are no exploitable bugs in perl itself, or apache, or the kernel, then, by running your web code as root, you're potentially handing root access to any random script kiddie on the internet.

If you really, truly, absolutely have no choice other than to have web-accessible code write arbitrary files to /, then the least-bad, least-insecure way to do it would be to create a very tiny helper program which takes a file name and file contents as inputs, checks to verify that the named file does not already exist (so that an attacker can't use it to overwrite, say, your kernel), and then creates the named file with the provided contents. Aside from maybe a little additional sanity/security checking, it should do absolutely nothing else because the more complex this helper program is, the more likely it is to contain exploitable flaws. Then have the web code use suid to run the helper program, with suid configured to allow the web user (and only the web user) to run the helper program (and only the helper program) with no password.

But don't do that unless you really, truly, absolutely have no other option. It is not the best way to do it, it is the least bad way. Which means it's still a bad idea.

Dave Sherohman
  • 45,363
  • 14
  • 64
  • 102
  • 1
    Thank you, mate! Great answer! What I decided is to create an installer for my software (a perl script) which will be ran under ROOT from terminal and it will create that files ONLY on the server side (not as a CGI) and ONLY ONCE on installation. The file that will be created will be deployed (as you greatly advised) in /etc or in /var/local/mysoftware – Arsenii Jul 19 '15 at 12:46
  • 1
    Sounds like a good plan. Running the installer from the command line instead of CGI/web is pretty much the best way of keeping it secure. – Dave Sherohman Jul 20 '15 at 09:04
1

You're executing your Perl program as a user without sufficient privilege. Run the Perl program using a user with sufficient privilege (e.g. using sudo or su).

ikegami
  • 367,544
  • 15
  • 269
  • 518