[Web-SIG] Proposed specification: developer authentication
Ian Bicking
ianb at colorstudy.com
Mon Mar 31 20:24:28 CEST 2008
I'm having some technical problems with wsgi.org, but once those are
figured out this will be posted to
http://wsgi.org/wsgi/Specifications/developer_auth
I'll let the spec speak for itself, I guess. I already have a half
dozen tools that could make use of this spec, and I know several other
tools that could also use it (TG toolbox, repoze.profile).
Comments encouraged. Or just agreement. Silence indicates lack of
interest.
:Title: Developer Auth
:Author: Ian Bicking <ianb at colorstudy.com>
:Discussions-To: Python Web-SIG <web-sig at python.org>
:Status: Proposed
:Created: 31-Mar-2008
.. contents::
Abstract
--------
Many tools can be written for a WSGI stack which should only accessible
to developers. For example, an interactive debugger in response to
sessions. Or a template system might display the underlying filenames
that created a page. Or profiling data. In some cases there are
security implications to exposing this data, in other cases it is
harmless but undesirable to show this information to normal users. This
specification offers a single, simple way to detect if a user should be
presented with this information.
Rationale
---------
So far these tools have been controlled by configuration, e.g., ``debug
= True``. This works but can be dangerous, as a deployer or developer
can forget to turn off tools. Or, if it is controlled through Python
code, it can be difficult to enable on a site that wasn't intended to
have the tool on, e.g., if you want to debug a live site because you
can't reproduce a problem in development. Also, configuration doesn't
allow some people to see these development tools while hiding them from
other people. A per-request and secure authentication method is more
desirable.
This could be implemented using application-specific authentication
methods and permission levels. This is undesirable because often
debugging is orthogonal to users -- you may want to debug a problem only
present when a low-permission or anonymous user is visiting the site.
Also it is difficult to keep application and debugging permissions
coherent, which is probably why this technique is not used by any tools.
Specification
-------------
Debugging tools should look for a key
``environ['x-wsgiorg.developer_user']``. This will contain some kind of
user name. If it is empty or not present, then debugging tools should
not activate themselves, or should not expose any information in the
browser.
The user name can be used in logging, but all users are considered to
have the same permission level (total access). The username must be a
``str``, but its contents are not constrained (an IP address, for
example, would be acceptable, or a name and email, with an embedded space).
If a URL is protected except for developers, applications should simply
return ``403 Forbidden``. Seamless login is not part of this
specification or its goals. Some systems may be IP-controlled, for
example, and no login is possible.
Example
--------
This is a simple exception catcher that uses the key::
import sys, traceback
class CatchExceptions(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
if not environ.get('x-wsgiorg.developer_user'):
return self.app(environ, start_response)
try:
return self.app(environ, start_response)
except:
start_response('500 Server Error', [('content-type',
'text/plain')],
sys.exc_info())
return [traceback.format_exc()]
Here is a IP-restricted middleware that sets the key::
class IPDeveloper(object):
def __init__(self, app, ips=('127.0.0.1',)):
self.app = app
self.ips = ips
def __call__(self, environ, start_response):
if environ.get('REMOTE_ADDR') in self.ips:
environ['x-wsgiorg.developer_user'] =
environ['REMOTE_ADDR']
return self.app(environ, start_response)
Problems
--------
* With security by obscurity in mind, it might be best if login methods
weren't clear. With ease of use in mind, easy logins are best.
* There's no levels of access. Everyone is assumed to have complete
access. (You could add another custom key if you want to share extra
information between the authentication and application layer.)
* This encourages people to do production deployments with debugging
tools enabled.
Other Possibilities
-------------------
* Configuration
* Conditional middleware composition
* Application login systems
* Some other generalized authentication system (AuthKit, etc).
Open Issues
-----------
* Should ``401 Authorization Required`` be returned? Potentially with
``WWW-Authenticate: x-wsgiorg.developer_user``. This would signal to
the middleware that a login should occur, which it may or may not ignore
(it could translate that to ``403 Forbidden``). This would make, for
example, HTTP Basic authentication doable (since that authentication is
per-request, and so you can't detect if a user already has logged in).
But HTTP Basic would probably be inappropriate for many systems, where a
page is *filtered* by authentication, it isn't blocked.
More information about the Web-SIG
mailing list