Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 May 2006 11:09:31 +0200
From:      Borja Marcos <BORJAMAR@SARENET.ES>
To:        Robert Watson <rwatson@FreeBSD.org>
Cc:        freebsd-security@freebsd.org
Subject:   Re: MAC policies and shared hosting
Message-ID:  <FDEE8EA9-0AA0-4CD9-854F-B543A1288101@SARENET.ES>
In-Reply-To: <20060504172309.D17611@fledge.watson.org>
References:  <CB6E482F-221F-4D31-8814-BF4A23D3E19E@SARENET.ES> <20060504172309.D17611@fledge.watson.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> I think the approach you've described sounds like the right sort of  
> approach -- a hybrid model that allows the web server to tell the  
> kernel when its switching to a particular user domain, taking  
> advantage of existing user credential elements, etc.  I guess what  
> I'd start out by doing is identifying what it is you want to  
> protect against, and specifically, write a couple of short stories  
> (a few sentences) describing specific sequences of events you want  
> to protect against with the policy.  It sounds like, in particular,  
> you're looking for an outcome that could be expressed using  
> mac_bsdextended, but perhaps not efficiently due to the number of  
> rules it would take to implement.

The problem is: Is it possible to run a shared web hosting for many  
servers (imagine 1000) on FreeBSD with a reasonable security level?  
Most of them would be low-traffic websites with a couple of .html  
files, some images... And some of them need the ability to run CGIs  
and PHP, which creates a real nightmare.

I know there exists the jail mechanism, but it's complex to manage,  
and you loose the flexibility of virtual hosts, needing a different  
IP address for each hosted server. Moreover, you need a lot of chroot  
trees (one for each user).

A hybrid scheme would need to create a single chroot, imagine:

/chroot/
/chroot/etc
/chroot/usr/

....

/chroot/webs/user1
/chroot/webs/user2


but it has an important shortcoming:

1- User directories must be visible in order to be accesible by  
unprivileged web server processes. However, it's not desirable to  
allow a CGI or PHP script by a given user to access a directory  
belonging to another user.

I would like the CGI and PHP scripts to be as flexible as possible,  
but without compromising the other users.


I had a look at the different MAC modules, and saw that  
mac_bsdextended could be really useful for this. However, it has some  
problems:

1- Lack of flexibility to specify general rules.

2- Rule number limitation, I guess because a lot of rules would  
impose a serious performance penalty. This could be changed by  
implementing a set of orderless rules stored in the form of a sparse  
matrix, so that an access from a subject with uid X to an object with  
uid Y would be checked in a very short time, instead of looking for a  
match for each of the rules.

So, for example, imagine that I want each uid belonging to the set  
[10000,20000] unable to act on objects belonging to users in the same  
range, I could define something like:

# deny for uid belonging to [10000,20000] on uid belonging to  
[10000,20000], being both # different
ugidfw add subject uid 10000-20000 object different uid 10000-20000 mode

# allow for uid belonging to the interval, on uid belonging to the  
same interval, being
# both uids the same
ugidfw add subject uid 10000-20000 object uid 10000-20000 mode arswxn


I'm testing this approach by a quick'n dirty way. I've got  
mac_bsdextended, and doing some trivial changes I've created a new  
mac module called mac_isolateduids. It specifies a range of uids  
(security.mac.isolateduid.uid_min and  
security.mac.isolateduid.uid_max). I've changed the  
mac_bsdextended_check so that:

if uid of subject belongs to [uid_min,uid_max] and uid of subject  
belongs to [uid_min,uid_max], and uid(subject) != uid(object) the  
access is always denied. It's a quick and dirty solution, but it  
would implement the desired behavior. I'm right now tinkering with it  
and will let you know the results :)

Of course, this policy could be extended, for example, to forbid  
execution of setuid/setgid programs, etc. Right now, mine is a simple  
experiment (but it could go into actual production). I think there is  
a great work in the MAC framework, but security policies are hard to  
understand, manage and implement. We should look for something  
similar to the Unix model, but more flexible.

Perhaps some rework of the whole bsdextended idea could enhance it.

Regarding the multi-level idea, it would be a second phase. I would  
like to be able to contain effectively a possible root escalation  
from a poorly written CGI or PHP script. I know, it would be anyway  
extremely hard. But if we could launch the web server process with an  
additional lower security level inherited by all of its child  
processes, we could prevent damage to the system even by a child  
processes that escalated to root.

I guess I should sit down this weekend and prepare a properly written  
paper, but I think the idea is quite clear here :)

The possible practical implementation of this scheme would use Zeus  
webserver, which has an option to execute each CGI with the uid of  
its owner. Of course, it could be interesting to add some  
functionality, for example, to Apache, in order to take advantage of  
the new security mechanisms.



Best regards,







Borja.




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FDEE8EA9-0AA0-4CD9-854F-B543A1288101>