Friday, May 6, 2016

Re: Django formset security and injecting PKs in formset hidden id fields

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBCAAGBQJXLSVAAAoJEC0ft5FqUuEhYsQQAIaH6gfzM6MWuiJetsehdeCd
MGzovbWPQU32zoGm74CMLsSDnz9qDBkSqKleZTX3vlE8JN4SxkDCU2pHUCNX87Mj
v1P1XJdPlaWtH0C0NQY65myL2p2neRZteGTCxN5IJuSbr08sG4bPF9RSOwT15rdO
Gt7+qOhi/Xdk1gZe7m7RyiiwbY0MEgHucx5VvY0OSLKz7a7edjUabHXD8BHCD4vZ
HtrnNncWfiZIVqCG2TTge3k6GTIx8dyKwwK1uI84x/1VPSksWSY5tKFC0Zpxaf8H
pZyIRtL56r6sepc8RNuY9e1uYVnGQ6fA8ArMk51OPU1cKd8IoWS4coJC3jEgBop6
wG3Kp3gTQgXEr07Iv6mYKUaJdiGAng1SujWP1EOWDeLKXzC94H50gBpreFIYxXZw
Bs8auQ3VYd08iAozuwmQXLi1kW8OQ1huNoo4DetCB+tPhWne0zFtRKwNKsrf3OQJ
g3HM+P0GwOYNktN1zITlJt3aA6KxQ+cPivJv2cpXYpKxsgbfhwl/lA6zFIDeydSz
zjnkY/a9UWkYJvt/rS1Ksuvh6dqg7api6Bind06uR9T/WAcomq+dtWunvJNjxlfG
KHWXHeH9P/2Z1U4ec8IliGGxULYgX5PfyE8ay0sHdR/a7TfCOZw+eZTx0+5UyumD
IkZK/gSOEXxaXT6t89mD
=2JD0
-----END PGP SIGNATURE-----
Hi Rob,

On 05/03/2016 12:23 PM, Rob Ladd wrote:
> I've noticed something troubling in Django formsets:
>
> Each formset.form has a hidden field with the id of the model being edited.
>
> All one would need to do is change this id and submit, and the default
> formset |clean()| or |save()| methods don't bat an eye.

First of all, if you believe that you've found a security issue in
Django, please err on the side of caution and email
security@djangoproject.com, rather than reporting it in public. Thanks!

Second: can you provide a sample project demonstrating the behavior you
describe? I'm unable to reproduce that behavior, and by code inspection
I don't see how that behavior could occur, either. If you pass in the
`queryset` keyword argument when instantiating the formset, only objects
matching that queryset will be editable via the formset. Meddling with
IDs will at best allow you to create a new object, never to edit one
that's outside of `queryset`. But formsets always allow creation of new
objects.

It is true that the given queryset could match some new object on submit
that wasn't part of the queryset when the formset was initially
displayed, if that object was created or edited such that it now matches
the queryset filters in the meantime. There isn't any reasonable way for
Django to address this problem: there isn't necessarily any location
available to store state in between display and submit other than the
page, and that's under the control of the user. You should just be sure
that the filters applied to the `queryset` accurately describe the
limitations you want applied to the editing abilities of the user being
shown the formset. In a typical use case, the `queryset` would apply a
filter like `(owner=request.user)`, allowing a user to edit only the
objects they own.

If you still believe you're seeing a security issue here, please email
security@djangoproject.com with step by step reproduction instructions.

Thanks,

Carl

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/572D253C.4070301%40oddbird.net.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment