On Sep 15, 2:57 pm, Luke Plant <l.plant...@cantab.net> wrote:
> OK, I'll wait and see.

Here's the code: http://github.com/simonw/django-safeform

>  * it requires using Django's form system.  I've got plenty of views that
> don't (e.g. anything with a dynamic number of controls).  People not using
> django.Forms are left out in the cold, or having to learn another way to do
> things.

I've covered this in django-safeform by exposing a low level interface
to the CSRF token creation and validation routines (in csrf_utils) -
see the readme for documentation on this.

>  * it's off by default.  Turning it on by default will require making
> django.forms.Form subclass SafeForm, which will almost certainly require a
> huge and immediate upgrade effort, because SafeForm cannot have the same API
> as Form.  If it's off by default, I see no point at all in this entire
> exercise.  If we don't arrive at a point where the POST form created in the
> tutorial is safe from CSRF, I think we've failed.

My priority for this is a little different: while I would dearly love
to see all Django applications secure against CSRF by default, I can't
see a way of doing it that doesn't break existing apps. More important
for me though is that the Django admin (and other reusable apps, such
as Pinax stuff) MUST be secure against CSRF out of the box, no matter
what the user puts in their settings.py file. If developers fail to
protect themselves (especially when the solution is well documented)
then at least it isn't our fault.

I think this is subtly different from the XSS escaping issue simply
because the solution to CSRF is much more intrusive.

> And it will still require changes to templates, just like the template tag,
> and it will also require changes to views, only significantly more complex  
> than simply using RequestContext.  It's got at least as many and at least as
> intrusive 'moving parts' AFAICS.

The SafeForm API actually simplifies views - you go from this:

def change_password(request):
    form = ChangePasswordForm()
    if request.method == 'POST':
        form = ChangePasswordForm(request.POST)
        if form.is_valid():
            return HttpResponse('Thank you')
    return render_to_response('change_password.html', {
        'form': form,
    })

To this:

@csrf_protect
def change_password(request):
    form = ChangePasswordForm(request)
    if form.is_valid():
        return HttpResponse('Thank you')
    return render_to_response('change_password.html', {
        'form': form,
    })

The SafeForm deals with the request.method == 'POST' bit, meaning one
less conditional branch within the view function itself.

I'm pretty happy with the SafeForm interface now that I've fleshed it
out - it's a lot less clunky than I was originally expecting.

Cheers,

Simon
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to