Setuid to Perl Script

Setuid to Perl script

"Insecure dependency" is a Taint thing: http://perldoc.perl.org/perlsec.html.

Taint is being enforced because you have run the script setuid. You need to specify untaint as an %option key to File::Find:

http://metacpan.org/pod/File::Find

my %options = (
wanted => \&wanted,
untaint => 1
);

find(\%options, $mqueue_directory);

You should also have a look at the untaint_pattern in the POD for File::Find.

How to successfully run Perl script with setuid() when used as cgi-bin?

The only way you can setuid to an arbitrary uid is to run as root.[1]

I don't know about you, but the idea of a CGI program running as root gives me nightmares.

What is this code supposed to actually do after changing uid? Perhaps there's a way to accomplish this without having to setuid?

[1] Depending on your code and its security model, you may be able to collect the user's password and use su/sudo[2] to run a separate command-line program to run the actual operations outside of the web server environment, but su/sudo are able to do this because they're suid root and it would still open up most/all of the issues associated with running CGI code as root anyhow. Even if you filter out root as an invalid username, being able to masquerade as any arbitrary user opens up plenty of opportunities for abuse.

[2] sudo could even be configured to allow it without requiring a password, but there be dragons down that path. Be sure you know what you're doing if you attempt it, lest you give your users free reign to impersonate each other at will.

Perl script to run as root (generalized)

After some brainstorming:

All the requirements can be met through the following steps. First we show steps which are done just once.

Step one. Since each script which should be run as root has to be marked by user root somehow (otherwise, just any user could do this), the system administrator takes advantage of his privileged status to choose a user ID which will never actually be assigned to anyone. In this example, we use user ID 9999.

Step two. Compile a particular C wrapper and let the object code run suid root. The source code for that wrapper can be found here.

Then, the following two steps are done once for each Perl script to be run as root.

Step one. Begin each Perl script with the following code.

if($>)
{
exec { "/path-to-wrapper-program" }
( "/path-to-wrapper-program",$0,@ARGV);
}

Step two. As root (obviously), change the owner of the Perl script to user 9999. That's it. No updating of databases or text files. All requirements for running a Perl script as root reside with the script itself.

Comment on step one: I actually place the above Perl snippet after these lines:

use strict;
use warnings FATAL=>"all";

... but suit yourself.

Passing command line arguments through a C setuid wrapper to another script

Here is a version dealing with a variable number of arguments. Please note that your syscalls should be tested to ensure everything is going OK.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>

#define CMDMAXLGTH 4096
#define SETUIDUSER "testuser"

int main( int argc, char ** argv ) {
struct passwd *pwd;
char user[] = SETUIDUSER;
char buf[CMDMAXLGTH];
char *p = buf;
int i = 1;

pwd = getpwnam(user);
// success test needed here
setuid(pwd->pw_uid);
// success test needed here

memset (buf, 0, sizeof(buf));
while (argv[i]) {
p += sprintf(p, " %s", argv[i++]);
}
system(buf);
return 0;
}


Related Topics



Leave a reply



Submit