Can I setuid a perl script?
Asked Answered
I

3

5

I made a perl script to change owner of a file owned by some other user. Script is complete. My administrator save that in /sbin directory and set uid for it using chmod u+s name_of_script. But when I run this script it gives me error that chown operation is not permitted. I made a C program and it works by following same steps. So my question is if setuid is working for perl then I should not get that error because C code did not give me any error. So can i setuid for perl script or I should go with c code.

Don't tell me to ask administrator to change owner each time. Actually in server I have user name staging and I am hosting a joomla site in it. Now when I install some plugin then files related to that plugin are owned by www-data. So that's why I do not want to go to admin each time. Or you can give me some other solution also regarding my problem.

Implode answered 6/2, 2014 at 8:9 Comment(0)
F
10

Many unix systems (probably most modern ones) ignore the suid bit on interpreter scripts, as it opens up too many security holes.

However, if you are using perl < 5.12.0, you can run perl scripts with setuid set, and they will run as root. How it works is that when the normal perl interpreter runs, and detects that the file you are trying to execute has the setuid bit set, and it then executes a program called suidperl. Suidperl takes care of elevating the user's privileges, and starting up the perl interpreter in a super-secure mode. suidperl is itself running with setuid root.

One of the consequences of this is that taint mode is turned on automatically. Other additional checks are also performed. You will probably see messages like:

Insecure $ENV{PATH} while running setuid at ./foobar.pl line 3.

perlsec provides some good information about securing such scripts.

suidperl is often not installed by default. You may have to install it via a separate package. If it is not installed then you get this message:

Can't do setuid (cannot exec sperl)

Having said all of that - you would be much better off using sudo to execute actions with elevated privileges. It is much more secure as you can specify exactly what is allowed to be executed via the sudoers file.

As of perl 5.12.0, suidperl was dropped. As a result, if you want to run a perl script on perl >= 5.12.0 with setuid set, you would have to write your own C wrapper. Again I recommend sudo as a better alternative.

Fluent answered 6/2, 2014 at 11:7 Comment(4)
how to install suidperl? apt-get install perl-suid is not working in debian wheezy. apt-cache search perl do not show anything related to suid. my script on execution show chown not permitted error. i am using perl 5.14.2Implode
@SumitRathore it seems that suidperl has been removed from perl at 5.12 (perldoc.perl.org/perl5120delta.html). That's rather unfortunate for your use case. Reading this thread nntp.perl.org/group/perl.perl5.porters/2008/12/msg142839.html it seems that you will have to either write your own C wrapper or use sudo. I will update the answer accordingly.Fluent
I'm going to throw a monkey wrench into this answer... It happens that setuid Perl scripts still work in Perl 5.22 and 5.16 on Solaris.Pacian
@BrianCowan that is not a result of suidperl, rather it is because Solaris still allows setuid on interpreter scripts. See #8314512Fluent
T
5

No, you cannot use setuid aka chmod +s on scripts. The script's interpreter would be the thing that would actually need to be setuid, but doing that is a really bad idea. REALLY bad.

If you absolutely must have something written in Perl as setuid, the typical thing to do would be to make a small C wrapper that is setuid and executes the Perl script after starting. This gives you the best of both worlds in having a small and limited setuid script but still have a scripting language available to do the work.

Tychonn answered 6/2, 2014 at 9:13 Comment(0)
D
0

If you have a sudo configuration that allows it (as most desktop linux distributions do for normal users), you can start your perl script with this line:

#!/usr/bin/env -S -i MYVAR=foo sudo --preserve-env perl -w -T

Then in your script before you use system() or backticks explicitly set your $ENV{PATH} (to de-taint it):

 $ENV{PATH} = '/usr/bin';

Other environment variable that your script explicitly mentions or that get implicitly used by perl itself will have to be similarly de-tainted (see man perlsec).

This will probably (again depending on your exact sudo configuration) get you to the point where you only have to type in your root password once (per terminal) to run the script. To avoid having to type your password at all you can add a line like this to the bottom of /etc/sudoers:

myusername ALL=(ALL) NOPASSWD:ALL

Of course you'd want to be careful with this on a multi-user system.

The -S options to env splits the string into separate arguments (making it possible to use options and combinations of programs like sudo/perl with the shebang mechanism). You can use -vS instead to see what it's doing.

The -i option to env clears the environment entirely.

MYVAR=foo introduces an environment variable definition.

The --preserve-env option to sudo will preserve MYVAR and others.

sudo sets up a minimal environment for you when it finds e.g. PATH to be missing.

The -i option to env and --preserve-env option to sudo may both be omitted and you'll probably end up with a slightly more extensive list of variables from your original environment including some X-related ones (presumably the ones the sudo configuration considers safe). --preserve-env without -i will end up passing along your entire unsanitized environment.

The -w and -T options to perl are generally advisable for scripts running as root.

Dallis answered 18/11, 2022 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.