(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`.

> All issues raised here are [[done]] --[[Joey]] 

[[!toc ]]

# 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. --[[Joey]]

>> Right, 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. --[[smcv]]

>>> Ok, 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:
>>> 
>>> 1. find a somehow exploitable apache.conf.tmpl on the host that's owned
>>>    by root, and move it into place.
>>> 2. race `ikisite enable`, which test the file owner and then reads it,
>>>    so it thinks it's reading a file owned by root.
>>> 3. 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.
> --[[Joey]]

>> My 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 earlier `suexec`
> 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. --[[smcv]]

>> And 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 by `root:b-example` so
>> the hosting user can (potentially) read their own logs later.
>> --[[smcv]]

>>> And 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]]
