Fixed security concerns:

Ikisite created a broken symlink for the git update hook, so pushes to the setup branch were not denied. This could possibly lead to unauthorized code execution, although it would have to be paired with a site branch or backup/restore.

This is fixed, but any existing sites need to have their update hook manually fixed to link to /usr/bin/iki-git-hook-update

done --Joey

Posted Fri Mar 25 01:18:47 2011

(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

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

Posted Sat Oct 2 15:06:11 2010

Need to deny pushes to the setup branch.

done

Posted Thu Apr 1 21:22:59 2010

Home directory perms currently allow global reading of most files. Lock down to 700?

I think I agree with 0700. Let's do that and see what breaks. --liw

The first thing to break will be apache, so this will need to be done with care.. Probably safest to only lock down source, source.git, ~/.git, ~/ikiwiki.setup.

Hmm, the git daemon and gitweb run unprivilidged and need access to source/.ikiwiki (gitweb config files could move elsewhere) and source.git .. --Joey

Would 0711 on the home dir work? Ah, but everyone will have files with well-known names. --?liw


Things that need to be readable by other than the site user:

  • ~/apache.conf (owned by root:root, and should not contain sensative stuff; the same info is filled into /etc/apache2 config files anyway)

Things that are already appropriatly locked-down:

  • logs
  • ~/.ssh/authorized_keys
  • ~/.ikisite-nonce (transient file)
  • backups
  • ~/ikiwiki.setup
  • ~/.gitconfig, ~/.gitignore
  • ~/.git/
  • ~/tmp/
  • ~/public_html (750; group www-data)
  • ~/source/.ikiwiki (other than the gitweb config files randomly located in here)
  • ~/source/.ikiwiki/gitweb* (with suexec changes, gitweb runs as user)
  • ~/source as a whole
  • ~/source.git (when branchability is disabled)
  • ~/customersite/
  • ~/apache/ (750; group www-data)

done

Posted Thu Mar 25 01:20:03 2010