You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by KaiGai Kohei <ka...@ak.jp.nec.com> on 2009/03/25 01:55:06 UTC

[idea] web-application security powered by SELinux

Hello,

Now I have considered the way to work web-applications with restrictive
privileges set based on an identification of the client. It enables to
check and prevent violated actions from (buggy) applications using
features provided by the operating system.

I'm concerned about most of web-application, such as PHP scripts, are
launched as part of web-server process itself. It also means all the
web-application instances share the same privilege set of the server
process, even if these are invoked on the requests come from different
users. In other word, we cannot apply valid access controls on them
(except for ones applied by web-application itself, but it is hard to
ensure they don't have security bugs), because it seems to the operating
system multiple processes/threads with same privileges run simultaneously.

If we can run web-applications with more restrictive privileges set
for each users, groups and so on, the operating system can acquire
any actions from userspace and apply its access control policies.
I assume SELinux as the operating system feature here, but not
limited to SELinux. I guess this discussion can be applied on any
other advanced security features also.

In my opinion, we need the following three facilities:

1. The backend identifies the client and decide what privileges should
   be assigned on the launched web-applications prior to its invocation.
   The existing http-authentication is a candidate, but we don't assume
   a certain method to identify the client.

2. The backend creates a one-time thread or process to handle the given
   requests, and assigns the new privileges, then launches the worker
   thread or process to invoke contents handler.

3. The backend wait for the completion of the worker. The reason why
   we don't use them again is that it is fundamentally danger to allow
   a path to revert the privileges of web-application.

Please note that we don't assume users who want to use this feature
give first priority for performance. It is a kind of security tradeoff.

One idea is to add a security focused MPM which provide above features
and hooks for external modules.
I've actually developed a working example based on the "prefork" MPM.
When it accepts a request from the client, it creates a one-time thread
and assigns a new security context (which is a privileges set in SELinux),
then invokes contents handler.

  http://code.google.com/p/sepgsql/source/browse/misc/httpd-selinux/

However, I don't adhere the current implementation as is.
I would like to have a discussion to brush up the idea to achieve
the goal and to get acceptance in the mainline.

Any comments, questions and others are welcome.

Thanks,
-- 
OSS Platform Development Division, NEC
KaiGai Kohei <ka...@ak.jp.nec.com>

Re: [idea] web-application security powered by SELinux

Posted by KaiGai Kohei <ka...@ak.jp.nec.com>.
The attached patch is a proof of the concept.

It adds two new hooks and a new module, which allows to launch
web-applications with restricted privileges.

The two new hooks gives a chance external modules to override
ap_process_async_request() and ap_process_request().
The new module (mod_selinux.c) overrides the hook and its handler
works as follows:

1. selinux_process_request() is invoked instead of the standard
   ap_process_request(), and it creates a one-time-thread called
   as worker. Then it waits for the completion of the worker thread.

2. The worker thread invokes ap_process_request().
   Please note that any contents handler is invoked in the context
   of worker thread.

3. The ap_run_fixups() hook is invoked during the ap_process_request(),
   then it wakes up selinux_fixup_context().

4. The selinux_fixup_context() refers its configuration file to
   check the mapping between a security context and http-user or
   source ip address.
   If it can find an entry which shows a privilege to be assigned,
   it replaces the current privilege by more restrictive one.

   (*) getcon_raw() is an API to get current privilege, and
       the setcon() is an API to set new privilege.
   (*) SELinux allows to assign a thread more restrictive privilege.

5. Then, ap_invoke_handler() is called with the restrictive privilge.
   If it tries to confidential resources, SELinux prevent the web
   application to access them without any exception.

6. The worker thread exits, then the parent handler wakes up.

I would like to see any opinion from httpd-dev folks.

At least, security issues in web applications are nightmare for us,
and we think a new idea is necessary to associate web-users and
privileges in operating-system level to apply comprehensive access
controls.

Thanks,

KaiGai Kohei wrote:
> I considered the previous proposal might be a bit abstract one, so
> it leads people confusion to find out what should be suggested.
> 
> I would like to focus more tangible issues at first, to gather
> attention and have a fruitful discussion. :-)
> 
> The purpose of my proposition is to launch web-applications
> with more restricted privileges set using SELinux. It enables
> to prevent that buggy web application leaks or manipulates
> confidential information, such as privacy, authentication info,
> credit card number and so on.
> In my opinion, two enhancements are necessary at least.
> 
> The one is identification of the client. It is necessary to decide
> what privileges set to be assigned. If we choose a storategy to
> associate http-username and its individual privileges, the simplest
> idea is to use a configuration file to map a http-username and its
> privilege (called as security context), as follows:
>   ----------------
>   # HTTP User and Security context
>   #   the server process works with system_u:system_r:httpd_t:s0
>   #   in the default security policy.
>   #
>   foo         system_u:system_r:httpd_unpriv_webapp_t:s0
>   var         system_u:system_r:httpd_unpriv_webapp_t:s0
>   baz         system_u:system_r:httpd_admin_webapp_t:s0
>   *           system_u:system_r:httpd_unauth_webapp_t:s0
>   ----------------
> Anyway, we have to decide what security context should be assigned
> on the web-application launched based on the attribute of client.
> Source IP addresses or authentication token can be candidates more
> than http-username.
> 
> The other is assignment of the privileges set on the context
> of web application. We need to execute ap_invoke_handler()
> with individual and more restricted privilege, but it should
> not affect any following requests.
> Because the thread/process to handle the requests is used
> again and again, we cannot assign restricted privilege directly.
> Thus, my idea is to create a one-time-thread to execute web
> application under the restrictive privilege. Please note that
> there is no difference between a path to revert its privilege
> and a risk of privilege escalation.
> The parent side simply waits for the completion of the worker
> thread. If we implement this feature as an external module,
> the following steps will be necessary.
> (I assume httpd-devel tree.)
> 
> 1) It registers its handler as the ap_hook_process_request().
> 
> 2) When it is invoked, the handler create a child thread then
>    pass into a sleep until the child works.
> 
> 3) The child assigns more restrictive privileges on itself
>    and invokes ap_process_request() to launch web applications.
>    Because its privileges are limited to necessity minimum,
>    launched web application cannot access violated resources
>    due to checks in the operating system.
> 
> 4) The child thread exits, then the handler (parent) wake up.
> 
> 5) The handler returns HTTP_OK to skip invocation of hardwired
>    ap_process_request().
> 
> I guess you wonder its performance penalty, but it assume
> the users of this feature don't give the highest priority
> on performance. It is a security tradeoff.
> 
> I would like to see the opinion from hackers of httpd.
> If we can achieve same or similar feature in another way,
> please tell me your opinion.
> 
> 
> BTW, we cannot apply the above storategy on the httpd-2.2.x
> series because it does not have ap_run_process_request() hook
> and ap_process_request() is commented out by CORE_PRIVATE.
> I don't know the release policy in this community.
> Is it impossible to backport these feature into the 2.2.x?
> 
> Thanks,
> 
> KaiGai Kohei wrote:
>> Hello,
>>
>> Now I have considered the way to work web-applications with restrictive
>> privileges set based on an identification of the client. It enables to
>> check and prevent violated actions from (buggy) applications using
>> features provided by the operating system.
>>
>> I'm concerned about most of web-application, such as PHP scripts, are
>> launched as part of web-server process itself. It also means all the
>> web-application instances share the same privilege set of the server
>> process, even if these are invoked on the requests come from different
>> users. In other word, we cannot apply valid access controls on them
>> (except for ones applied by web-application itself, but it is hard to
>> ensure they don't have security bugs), because it seems to the operating
>> system multiple processes/threads with same privileges run simultaneously.
>>
>> If we can run web-applications with more restrictive privileges set
>> for each users, groups and so on, the operating system can acquire
>> any actions from userspace and apply its access control policies.
>> I assume SELinux as the operating system feature here, but not
>> limited to SELinux. I guess this discussion can be applied on any
>> other advanced security features also.
>>
>> In my opinion, we need the following three facilities:
>>
>> 1. The backend identifies the client and decide what privileges should
>>    be assigned on the launched web-applications prior to its invocation.
>>    The existing http-authentication is a candidate, but we don't assume
>>    a certain method to identify the client.
>>
>> 2. The backend creates a one-time thread or process to handle the given
>>    requests, and assigns the new privileges, then launches the worker
>>    thread or process to invoke contents handler.
>>
>> 3. The backend wait for the completion of the worker. The reason why
>>    we don't use them again is that it is fundamentally danger to allow
>>    a path to revert the privileges of web-application.
>>
>> Please note that we don't assume users who want to use this feature
>> give first priority for performance. It is a kind of security tradeoff.
>>
>> One idea is to add a security focused MPM which provide above features
>> and hooks for external modules.
>> I've actually developed a working example based on the "prefork" MPM.
>> When it accepts a request from the client, it creates a one-time thread
>> and assigns a new security context (which is a privileges set in SELinux),
>> then invokes contents handler.
>>
>>   http://code.google.com/p/sepgsql/source/browse/misc/httpd-selinux/
>>
>> However, I don't adhere the current implementation as is.
>> I would like to have a discussion to brush up the idea to achieve
>> the goal and to get acceptance in the mainline.
>>
>> Any comments, questions and others are welcome.
>>
>> Thanks,
> 
> 


-- 
OSS Platform Development Division, NEC
KaiGai Kohei <ka...@ak.jp.nec.com>

Re: [idea] web-application security powered by SELinux

Posted by KaiGai Kohei <ka...@ak.jp.nec.com>.
I considered the previous proposal might be a bit abstract one, so
it leads people confusion to find out what should be suggested.

I would like to focus more tangible issues at first, to gather
attention and have a fruitful discussion. :-)

The purpose of my proposition is to launch web-applications
with more restricted privileges set using SELinux. It enables
to prevent that buggy web application leaks or manipulates
confidential information, such as privacy, authentication info,
credit card number and so on.
In my opinion, two enhancements are necessary at least.

The one is identification of the client. It is necessary to decide
what privileges set to be assigned. If we choose a storategy to
associate http-username and its individual privileges, the simplest
idea is to use a configuration file to map a http-username and its
privilege (called as security context), as follows:
  ----------------
  # HTTP User and Security context
  #   the server process works with system_u:system_r:httpd_t:s0
  #   in the default security policy.
  #
  foo         system_u:system_r:httpd_unpriv_webapp_t:s0
  var         system_u:system_r:httpd_unpriv_webapp_t:s0
  baz         system_u:system_r:httpd_admin_webapp_t:s0
  *           system_u:system_r:httpd_unauth_webapp_t:s0
  ----------------
Anyway, we have to decide what security context should be assigned
on the web-application launched based on the attribute of client.
Source IP addresses or authentication token can be candidates more
than http-username.

The other is assignment of the privileges set on the context
of web application. We need to execute ap_invoke_handler()
with individual and more restricted privilege, but it should
not affect any following requests.
Because the thread/process to handle the requests is used
again and again, we cannot assign restricted privilege directly.
Thus, my idea is to create a one-time-thread to execute web
application under the restrictive privilege. Please note that
there is no difference between a path to revert its privilege
and a risk of privilege escalation.
The parent side simply waits for the completion of the worker
thread. If we implement this feature as an external module,
the following steps will be necessary.
(I assume httpd-devel tree.)

1) It registers its handler as the ap_hook_process_request().

2) When it is invoked, the handler create a child thread then
   pass into a sleep until the child works.

3) The child assigns more restrictive privileges on itself
   and invokes ap_process_request() to launch web applications.
   Because its privileges are limited to necessity minimum,
   launched web application cannot access violated resources
   due to checks in the operating system.

4) The child thread exits, then the handler (parent) wake up.

5) The handler returns HTTP_OK to skip invocation of hardwired
   ap_process_request().

I guess you wonder its performance penalty, but it assume
the users of this feature don't give the highest priority
on performance. It is a security tradeoff.

I would like to see the opinion from hackers of httpd.
If we can achieve same or similar feature in another way,
please tell me your opinion.


BTW, we cannot apply the above storategy on the httpd-2.2.x
series because it does not have ap_run_process_request() hook
and ap_process_request() is commented out by CORE_PRIVATE.
I don't know the release policy in this community.
Is it impossible to backport these feature into the 2.2.x?

Thanks,

KaiGai Kohei wrote:
> Hello,
> 
> Now I have considered the way to work web-applications with restrictive
> privileges set based on an identification of the client. It enables to
> check and prevent violated actions from (buggy) applications using
> features provided by the operating system.
> 
> I'm concerned about most of web-application, such as PHP scripts, are
> launched as part of web-server process itself. It also means all the
> web-application instances share the same privilege set of the server
> process, even if these are invoked on the requests come from different
> users. In other word, we cannot apply valid access controls on them
> (except for ones applied by web-application itself, but it is hard to
> ensure they don't have security bugs), because it seems to the operating
> system multiple processes/threads with same privileges run simultaneously.
> 
> If we can run web-applications with more restrictive privileges set
> for each users, groups and so on, the operating system can acquire
> any actions from userspace and apply its access control policies.
> I assume SELinux as the operating system feature here, but not
> limited to SELinux. I guess this discussion can be applied on any
> other advanced security features also.
> 
> In my opinion, we need the following three facilities:
> 
> 1. The backend identifies the client and decide what privileges should
>    be assigned on the launched web-applications prior to its invocation.
>    The existing http-authentication is a candidate, but we don't assume
>    a certain method to identify the client.
> 
> 2. The backend creates a one-time thread or process to handle the given
>    requests, and assigns the new privileges, then launches the worker
>    thread or process to invoke contents handler.
> 
> 3. The backend wait for the completion of the worker. The reason why
>    we don't use them again is that it is fundamentally danger to allow
>    a path to revert the privileges of web-application.
> 
> Please note that we don't assume users who want to use this feature
> give first priority for performance. It is a kind of security tradeoff.
> 
> One idea is to add a security focused MPM which provide above features
> and hooks for external modules.
> I've actually developed a working example based on the "prefork" MPM.
> When it accepts a request from the client, it creates a one-time thread
> and assigns a new security context (which is a privileges set in SELinux),
> then invokes contents handler.
> 
>   http://code.google.com/p/sepgsql/source/browse/misc/httpd-selinux/
> 
> However, I don't adhere the current implementation as is.
> I would like to have a discussion to brush up the idea to achieve
> the goal and to get acceptance in the mainline.
> 
> Any comments, questions and others are welcome.
> 
> Thanks,


-- 
OSS Platform Development Division, NEC
KaiGai Kohei <ka...@ak.jp.nec.com>