Comment exécuter avec succès un script Perl avec setuid() lorsqu'il est utilisé comme cgi-bin ?
Question
J'ai un script Perl qui est appelé via Apache ou sur la ligne de commande.
À des fins de test, je lui transmets le nom d'utilisateur avec lequel je souhaite que le script Perl fonctionne et j'utilise POSIX::setuid
pour régler le uid
.
Si j'exécute le script depuis la ligne de commande, alors le uid
est correctement réglé :
use CGI::Pretty qw/:standard/;
use POSIX qw(setuid getuid);
...
my ($pwName, $pwCode, $pwUid, $pwGid, $pwQuota, $pwComment,
$pwGcos, $pwHome, $pwLogprog) = getpwnam($username);
if ((defined $pwUid) && (getuid() == $pwUid)) {
setuid($pwUid);
print header;
print Dumper $<;
}
else {
print header(-status => 401);
print "Could not setuid to correct uid (currently: )".getuid()."\n";
}
La sortie de la ligne de commande affiche le bon uid
du spécifié $username
, à la place du uid
du compte de test qui a commencé à exécuter le script.
Si j'appelle le script via Apache, alors le uid
reste défini sur l'identifiant du apache
utilisateur, et ne change jamais.
Je ne crois pas pouvoir utiliser suExec
ici, car, après avoir lu la documentation :
Je ne peux pas mettre une copie de ce script dans
http://www.example.com/~username
pour chaque$username
.Le script doit être exécuté à partir d'un seul emplacement et je dois spécifier leuid
à partir du script.Je dois exécuter le script sous le nom d'utilisateur spécifié au moment de l'exécution, et non sous le nom d'un nom d'utilisateur unique spécifié une fois dans une directive d'hôte virtuel dans un fichier de configuration Apache.Changer ce fichier de configuration et redémarrer Apache à chaque fois qu'un nouvel utilisateur exécute ce script n'est pas réaliste.
Comment puis-je exécuter un script Perl en tant que cgi-bin pour modifier le uid
correctement, lors de l'utilisation setuid()
?
La solution
La seule façon pour toi de pouvoir setuid
à un UID arbitraire est de s'exécuter en tant que root.[1]
Je ne sais pas pour vous, mais l'idée d'un programme CGI exécuté en tant que root me donne des cauchemars.
Qu'est-ce que ce code est censé faire après avoir modifié l'uid ?Il existe peut-être un moyen d'y parvenir sans avoir à le faire setuid
?
[1] En fonction de votre code et de son modèle de sécurité, vous pourrez peut-être collecter le mot de passe de l'utilisateur et utiliser su
/sudo
[2] pour exécuter un programme de ligne de commande distinct pour exécuter les opérations réelles en dehors de l'environnement du serveur Web, mais su
/sudo
sont capables de le faire parce qu'ils sont suid root et cela ouvrirait de toute façon la plupart/tous les problèmes associés à l'exécution du code CGI en tant que root.Même si vous filtrez root en tant que nom d'utilisateur invalide, le fait de pouvoir vous faire passer pour n'importe quel utilisateur arbitraire ouvre de nombreuses possibilités d'abus.
[2] sudo
pourrait même être configuré pour l'autoriser sans nécessiter de mot de passe, mais il y a des dragons sur ce chemin.Assurez-vous de savoir ce que vous faites si vous essayez, de peur de laisser libre cours à vos utilisateurs pour se faire passer pour les uns les autres à volonté.