(I originally reported this by private email, but Joey is fairly sure it's not exploitable on branchable.com, so I'm summarizing discussion here. --smcv)
By design, the hosted users aren't meant to be able to execute arbitrary code.
However, if they can (due to a bug), they can get arbitrary code executed as
www-data
, at which point they can interfere with other users, steal
httpauth
passwords (although those aren't supported on branchable.com
),
and so on.
For this page I'll assume that the user trying to escalate privilege is
b-example
.
open issues
apache.conf.tmpl
apache.conf.tmpl
is, if not root-equivalent, then at least www-data
-equivalent,
because it can set security-related Apache configuration. I've noticed that it's
not backed up, but it is restored from backups and chown
'd to root, so restoring
an untrusted backup is currently dangerous.
apache.conf.tmpl
is backed up; it's committed to the setup branch.Restoring from an untrusted backup is dangerous anyway, because for example
ikiwiki.setup
can be configured to make ikiwiki run arbitrary code. All the dangerous stuff should be confined to the setup branch, which is why pushing that branch is rejected. --JoeyRight, but my goal with this stuff is more or less: if bob is a user with shell access and b-example is his website, giving bob permission to become
b-example
via sudo doesn't let him escalate privileges any further than that. --smcvOk, so the risk with apache.conf.tmpl is that while it's owned by root, the site user can move it out of the way. This allows three attacks:
- find a somehow exploitable apache.conf.tmpl on the host that's owned by root, and move it into place.
- race
ikisite enable
, which test the file owner and then reads it, so it thinks it's reading a file owned by root.- move it out of the way, put in a bad file, let
ikisite backup
, back it up, and then use some method to get the site restored; restore will trust the file and make it owned by root.1 is unlikely, 3 can be fixed in
ikisite backup
perhaps, 2 should be solvable, with some difficulty (I think that hard linking the file and checking the owner of the hard link, the reading the hard link, would work?) Still, keeping the file in $HOME is not looking very smart. --Joey
Since only root can set this up anyway, I'd personally be inclined to treat
it as server-wide configuration that should be backed up as part of /etc
,
There will be frontends to configure common stuff in it later, and it is site-specific apache configuration, that needs to be transferred along with the site if it is, say, bundled and transferred to a different server.
What could be done is to use
apache-site.tmpl
, and add to it variables exposing and configuring stuff like htpasswd setup or whatever else is needed (we have some collectd monitoring snippets in one of our sites at branchable, for example). Then have ikiwiki.setup hold the configuration for those variables. --JoeyMy feeling about moving the config to a site-wide template file(s) that are then enabled by ikiwiki.setup settings is that it's great for common things, but it loses a lot of easy flexability of being able to go in and use the full power of apache to tweak sites, in an ad-hoc way. That is flexability and power that I'm uncertian about sacrificing. --Joey
create /etc/apache2/ikisite
, and put something like this in apache-site.tmpl
:
<VirtualHost *:80>
ServerName <TMPL_VAR HOSTNAME>:80
...
Include /etc/apache2/ikisite/<TMPL_VAR USER>.*.conf
</VirtualHost>
<VirtualHost *:80>
ServerName <TMPL_VAR HOSTNAME>:80
...
Include /etc/apache2/ikisite/src.<TMPL_VAR USER>.*.conf
</VirtualHost>
Then you can put whatever you want in those files. Note that Apache considers
it to be a syntax error if an Include
directory doesn't exist, but is
perfectly happy if a glob fails to match any files.
If the HTML::Template
functionality is useful in practice (is it?),
ikisite
could perhaps automatically generate foo.conf
from foo.tmpl
.
I haven't done this on my branch so far. --smcv
This is fine, except it adds a second thing that needs to be managed and transferred along with ikisite backups to move sites. It's important to me that ikisite sites be self-contained at the backup level. Now, the backups could be modified to include the site's file from /etc in them, and restore to restore them, I suppose.. --Joey
Ok, I have done something based on this but without the includes. I did keep the
HTML::Template
functionality, it's useful to have branchable sites whose apache config tweaks follow them when branched. Generalized to a/etc/ikiwiki-hosting/config/$user/
directory for root-owned configs. --Joey
resolved issues
IkiWiki CGI
If the user can remove the setuid/setgid bits from their ikiwiki.cgi wrapper
(which they own), it'll execute as www-data
. They could then get anything
executed with www-data
privileges.
Possible fixes:
Use Apache's suexec
Something like this: http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/escalation. (If you don't want to put the Debian dependencies one per line, leave out that commit, but I find git diff isn't very useful for long dependency lists otherwise...)
suexec will only work if the CGI script is under /var/www, owned by
b-example
, not writeable by anyone else, and in a directory also meeting
those conditions; CGIs not meeting those conditions won't be executed at
all.
Done in your branch, which I've merged. --Joey
Central setuid-root wrapper
Have a central setuid-root wrapper /usr/lib/ikiwiki-hosting/ikiwiki.cgi
which is only executable by www-data, and when run with
IKISITE_USER=b-example
or something, switches user/group to b-example
and execs /home/b-example/public_html/ikiwiki.cgi
. This is basically
reinventing suexec.
Joey pointed out that because ikiwiki plugins are allowed to add C code to
the cgi_wrapper
, every site's C CGI wrapper can be different, so the
central setuid-root wrapper would have to be a wrapper for a wrapper.
Gitweb CGI
gitweb
will run arbitrary Perl code from .ikiwiki/gitweb.conf.real
.
Possible fixes:
Configuration elsewhere
Put the gitweb.conf somewhere else (/var/lib/ikiwiki-hosting-web/gitweb
?)
and have root own it, so www-data
can't be subverted.
Use suexec
again
Install a wrapper in each user's suexec
directory, owned by the user
themselves, so that each user's gitweb runs with the privileges of that user,
via suexec. The wrapper can be as simple as this: the important thing for
suexec is that the user owns it.
#!/bin/sh
exec /usr/lib/cgi-bin/gitweb.cgi "$@"
As noted on homedir perms this has the nice side-effect that more of the home directory can be private.
I've done this on my
escalation
branch, which is the earliersuexec
branch redone so that existing users will (mostly) keep working, with their old log/CGI directory (if you disable/enable sites it might still break, not sure). It'd be great if you could merge some or all of this. --smcvAnd merged. --Joey
ikisite parsing ikiwiki.setup
ikisite loads ikiwiki.setup
in "safe mode", so hopefully there's no
possibility of arbitrary code execution there.
Specifically, safe mode prevents ikiwiki.setup from being a perl script. Of course, if any value is used in an insecure way by ikisite, it loses. --Joey
I haven't audited this thoroughly yet, but nothing jumps out at me... --smcv
logs
http://httpd.apache.org/docs/2.2/misc/security_tips.html#serverroot says:
If the logs directory is writeable (by a non-root user), someone could replace a log file with a symlink to some other system file, and then root might overwrite that file with arbitrary data.
I don't know how plausible that is in practice, but on shared hosting services I've used in the past, the base directory for my website has been owned by root, with docroot, cgi-bin etc. subdirectories owned and writeable by me, and a logs directory not owned by me.
If you want users to own their own home directories (which ikisite
does currently assume), an alternative way to do this would be to
put the logs in /var/log/apache2/b-example/
or
/var/log/apache2/example.branchable.com/
or whatever, and have
the home directory contain a logs/ symlink for convenience?
I think it's reasonable to move the logs outside of home. Having a symlink would only encourage something to write through the symlink, breaking security again. The other issue with having them outside of home is /var needs to have space for them -- but this also means that something filling the logs doesn't necessarily full the home partition too. --Joey
I've added that to my branch; I used
/var/log/ikiwiki-hosting/b-example
owned byroot:b-example
so the hosting user can (potentially) read their own logs later. --smcvAnd merged. --Joey
users not owning their own $HOME?
One way to avoid various privilege escalations would be for the site users' home directories to be owned by root and not writeable by the user, with particular subdirectories writeable. Things that that would break:
- the code in ikisite that replaces ikiwiki.setup
- ikiwiki.setup in general, possibly, depending how ikiwiki rewrites it (an easy workaround would be to put it in a subdirectory)
- any random program that assumes it can replace a dotfile by creating a temporary file and renaming over the original
Probably not worth it...
I agree, this is not an approach I really want to pursue. --Joey
~/apache/
I don't know what you put in here in practice, so I don't know whether it can cause privilege escalation
Currently, only htpasswd files. Exploitability unlikely. --Joey