You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Donald Buczek <bu...@MPIMG-Berlin-Dahlem.MPG.DE> on 1998/09/04 17:43:03 UTC

suEXEC alternative. Please comment.

Hello,

I've thought of (and implemented) an alternative to suEXEC and its
security model. I might have overlooked something. If not, it might
be usefull to other as well. Therefore I ask for your comments.

Overview:

The web server runs uid/gid wwwserver/wwwserver. This uid is as much
trusted as the web administrator and the server config is.

Normal cgi-scripts run uid wwwcgi. This uid is less trusted (like
nobody). So normal cgi-scripts don't have implied access to any file
the server has access to. Documents or config files (.htaccess, password
files) can be made readable to wwwserver only.

As usual on unix, users are free to create setuid scripts. As opposed to
suEXEC, making a script setuid is the only way to get a transition to
a uid different from the default (wwwcgi). So this transition is only
at the explicit decision of the owner of the program and never implied.

The last step is to make a setuid-script able to verify that its cgi
environment (e.g.. REMOTE_USER) comes from the web server and not from
another user. This can be done by denying execute access to everybody
but the owner itself. Only the owner himself (e.g.. for debugging) or
some root-blessed process (like the web server with the help from
its wrapper) is able to execute the program - as a proof the
environment is 'blessed' by the owner or root. (The modes for such a
script would be rws------ ).

The last step was the one I was really after, because currently
server-based authorization and privileged cgi-programs don't mix well.
The current suEXEC never can make sure that it was called from the
server (and not from another cgi-script, which did some 'corrections'
to the environment). So the scripts never can be sure - even if
suEXEC proved its privilege by chaning the UID.

By 'lowering' the UID to wwwcgi whenever code outside the server
is executed, the wrapper can be sure it was called from the
web-server (=some entity under the control of the web administrator)
and not from user code. By executing the programm, which denies
execute to the public, the wrapper prooves its identity to the
script. So the script can imply "root says, this is a request
authorized by the web administrator".

I hope you see the advantages over suEXEC. Here are some:

- the security of the whole system doesn't depend on the web-server
with its complicated configuration or the person of the web
administrator.

- no surprises of what is to be run setuid-owner.

- documents, accessible from the web server, can be protected from
being accessed by cgi-scripts bypassing the access restrictions of
the server.

- some security features from the operating system are left intact.
(chown resets the setuid bit, LD_LIBRARY_PATH gets fixed etc.)

- privileged cgi-scripts can (optionally) get some trust in their
environment.

- the changes to the apache source are minimal (4 lines of code) and
the wrapper (which needs to be setuid-root) is much shorter
(more secure, faster).

Here are the changes to apache:

 main/util_script.c:
  change the three exec*() calls to call the wrapper. Use the full
  pathname (r->filename) as argv[0] instead of the basename argv0
 
 modules/mod_cgi.c
  disabled the check producing "file permissions deny server
  execution" based on the programs mode bits. (This check isn't needed
  for security, because anyway exec() knows better about what is
executable
  and what is not).

That's it. I attach the wrapper code I use. It still uses hardcoded UIDs
and is not platform independent.

If you followup to the list, I'd appreciate a cc:

Thanks
  Donald Buczek

-- 
Donald Buczek
buczek@MPIMG-Berlin-Dahlem.MPG.DE
+49 30 8413 1433