[Zope-dev] startup security status (say that five times fast... well, ok, it wasn't so tough after all)

Behrens Matt - Grand Rapids Matt.Behrens@Kohler.Com
Wed, 24 Oct 2001 07:35:27 -0400


I have a patch in hand that addresses MOST of the issues I brought up, 
but the biggie (tricking root into killing arbitrary processes) is a 
hard one to solve.  I have many options, and I'd like opinions...

Right now, the pid file is written out by the user that ZServer drops to 
after starting.  This is bad because if that user is compromised, the 
pid file can be overwritten, and root can be tricked into killing (an) 
arbitrary process(es) the next time 'stop' is run.

The obvious solution was to move the writing of the file up before the 
setuid() call.  Now, the unprivileged user can't *change* the pid file. 
  However, because the var directory must be writable by the 
unprivileged user, the unprivileged user can *remove* then *rewrite* the 
pid file, and we're back where we started.

Solutions:

1.  Have the stop script check ownership of the pid file to make sure 
it's still root's baby.  This solution seems easiest, but something 
about it doesn't seem right to me.  When something doesn't feel right to 
me, there's probably a way to fool it...

2.  Enforce the sticky bit on the var directory.  From Solaris' chmod(2) 
manpage:

      If a directory is writable and has S_ISVTX (the sticky  bit)
      set,  files  within that directory can be removed or renamed
      only if one or more of the following is true (see  unlink(2)
      and rename(2)):

         o  the user owns the file

         o  the user owns the directory

         o  the file is writable by the user

         o  the user is a privileged user

(Privileged user means 'root'.)  We only need to enforce the sticky bit 
if we start as root and are doing the requisite setuid().  My patch 
already has a test for this.

3.  Have the pid file written into another directory that only root can 
write to.

The rest of this should probably be another mail, but I figured I'd 
cover what my patch also does:

1.  No longer defaults to running as 'nobody'.  As I've explained, 
running as 'nobody' and the requisite permission settings that need to 
go with running as 'nobody' can set your Zope data up for compromise on 
your local system.  If -u is not specified z2.py will SystemExit.

2.  Warns you if you decide that you REALLY want to run as 'nobody', 
either with -u or by being nobody when starting z2.

3.  Tells you when and who it actually setuid()s to.

4.  Warns you if your umask isn't sufficient to protect your data files 
(experiment: pack your Data.fs and check its permissions.)

All messages in this patch are going through zLOG for cleanliness' sake.

-- 
Matt Behrens <matt.behrens@kohler.com>
System Analyst, Baker Furniture