sludin / Protocol-ACME

A perl library that provides a simple interface to writing scripts for cert provisioning with Let's Encrypt.
24 stars 7 forks source link

Permission denied while creating well-known dir #32

Closed twouters closed 8 years ago

twouters commented 8 years ago

There seems to be an issue in https://github.com/sludin/Protocol-ACME/blob/416f7a2552b5d2caeaa1e8c1cb513fe6806b572f/lib/Protocol/ACME/Challenge/LocalFile.pm#L129

Attempting to create the $www_root/.well-known/acme-challenge/ path results in a Permission denied error in the following situation:

Prepare directory tree (as root):

mkdir -p /var/www/website/web_root
chown 80:7000 /var/www/website
chmod 570 /var/www/website
chown 7000:7000 /var/www/website/web_root

Test script:

#!/usr/bin/env perl

my $www_root = '/var/www/website/web_root';
my ($uid,$gid) = (stat $www_root)[4,5];
local $> = $uid;local $) = $gid;
umask 022;
my $dir = "$www_root/.well-known/acme-challenge";
system "mkdir","-p",$dir;

Testing results in a Permission denied error (as root):

# perl test.pl
mkdir: cannot create directory `/var/www/website': Permission denied

Changing line 5 in the test script to the following fixes the issue:

local $) = $gid;local $> = $uid;
sludin commented 8 years ago

What OS/Version/Perl Version are you using? I cannot see how switching the other of the assignments would make a difference, though I do not deny your testing. Before I accept the change I'd like to get a bit more background on the root cause.

hoytech commented 8 years ago

I didn't look into this issue closely, but usually you want to drop group privs before user privs:

https://www.securecoding.cert.org/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges

Note the linux manpage says "it is a grave security error to omit checking for a failure return from seteuid()."

$ sudo perl -E '$> = 1000; say $! if $!; $) = 1000; say $! if $!;'
Operation not permitted
$ sudo perl -E '$) = 1000; say $! if $!; $> = 1000; say $! if $!;'
$
hoytech commented 8 years ago

I meant to add: I very much doubt that this case is a "grave security error". :)

Still, it's a good idea to check system calls for any error conditions.

twouters commented 8 years ago

I'm running this on Debian wheezy, perl version 5.14.2. I ran the test script with strace and it threw an "-1 EPERM (Operation not permitted)" error while changing the group id and it sort of made sense to me that an unprivileged user was unable to change its effective groupid. Will try to get more details on the setup.

Same on Ubuntu 14.04.4 LTS - perl 5.18.2

twouters commented 8 years ago

Found this thread which looks related https://lwn.net/Articles/621617/

sludin commented 8 years ago

Thank you. The link below nailed it - and once pointed out it is obvious. Learned something new.

-stephen

From: Doug Hoyte notifications@github.com Reply-To: sludin/Protocol-ACME reply@reply.github.com Date: Friday, April 29, 2016 at 12:02 PM To: sludin/Protocol-ACME Protocol-ACME@noreply.github.com Cc: Stephen Ludin sludin@ludin.org, Comment comment@noreply.github.com Subject: Re: [sludin/Protocol-ACME] Permission denied while creating well-known dir (#32)

I didn't look into this issue closely, but usually you want to drop group privs before user privs:

https://www.securecoding.cert.org/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges

Note the linux manpage says "it is a grave security error to omit checking for a failure return from seteuid()." $ sudo perl -E '$> = 1000; say $! if $!; $) = 1000; say $! if $!;' Operation not permitted $ sudo perl -E '$) = 1000; say $! if $!; $> = 1000; say $! if $!;' $ — You are receiving this because you commented. Reply to this email directly or view it on GitHub