2009/3/26 Robert Marianski <rmarian...@openplans.org>:
> I'm not sure how far along you've gotten here, but I have an interest in
> it too. I have access to update the csrfmiddleware, so if you think it's
> easier to make updates rather than start a new project, I'll be happy to
> work with you here.

I think we could work on ``csrfmiddleware``, bringing in the
functionality we need. Meanwhile, I've updated the project manifesto
(see attachment). It now relies on a named cookie rather than the
``repoze.who`` environment. This should help making it more general.

\malthe
Overview
========

This package provides a WSGI middleware which relies on ``repoze.who``
cookie authentiation to implement CSRF form protection [1].

Strategy
--------

In order to ensure that POST requests (which may be assumed to have
side-effects) stem from authorized forms, requests must include a
parameter that can only be known in theory by the authenticated user
and the website.

Such parameters are typically found in cookies; for example, a session
id or a login credentials token.

To configure the parameter, the middleware expects a ``cookie``
argument which names this cookie. A token is then created based on a
configurable seed argument (``seed``) and the cookie value. Only
requests that can produce this token are allowed (the "403 Forbidden"
status is returned otherwise).

It's imperative that the token is not discoverable by third party.

Note that this middleware only aims to protect from unauthorized, but
identified requests.

Getting and setting the validation token
----------------------------------------

On ingress, before looking at the POST data, the middleware consults
the "X-Form-Protect" request header. If not present, the POST data is
examined for a "__protect" key.

To-Be-Determined: On egress, we'll need to set a header which will be
readily available to the javascript vm on the client side, e.g. a
cookie. In general, response headers are *not*
available. Alternatively, developers will need to hardcode the
protection key into their javascript Ajax-calls, but this is a bit
cumbersome.

Form authentication
-------------------

The middleware intercepts HTML content in egress and adds a hidden
"__protect" field to all forms appearing on the page and which use the
POST request type.

In ingress, the parameter is stripped from the request before it
reaches the WSGI application.
  
Ajax support
------------

Using a JavaScript library such as jQuery, it's possible to submit
Ajax-requests that use the POST request method, without the use of a
form.
 
In order to authenticate such requests, either a valid form protection
parameter or request header must be submitted (see above).

To enable for all ajax-requests, bind an event listener for the jQuery
"ajaxSend" event, which adds the form validation request header [2].

  jQuery.bind("ajaxSend", function(event, request, settings) {
     request.setRequestHeader("X-Form-Protect", header)
  });

Note that ``header`` will need to be retrieved somehow, either from
the response or hardcoded by the application serving up the
javascript.

References
----------

[1] http://en.wikipedia.org/wiki/Cross-site_request_forgery
[2] http://www.w3.org/TR/XMLHttpRequest/#xmlhttprequest

Author
------

Malthe Borch <mbo...@gmail.com>
_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to