Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

session_csrf accesses POST on non-POST requests, which breaks piston #12

Open
scjody opened this issue Sep 6, 2012 · 0 comments
Open

Comments

@scjody
Copy link
Contributor

scjody commented Sep 6, 2012

When session_csrf is used in conjunction with piston to protect a PUT request, things break:

File "/home/scjody/pwbank/src/hg/web-banking/lib/python2.6/site-packages/django/views/decorators/vary.py", line 19, in inner_func
  response = func(*args, **kwargs)
File "/home/scjody/pwbank/src/hg/web-banking/src/trustcentric/resource.py", line 101, in __call__ 
  coerce_put_post(request)
File "/home/scjody/pwbank/src/hg/web-banking/lib/python2.6/site-packages/piston/utils.py", line 144, in coerce_put_post
  request._load_post_and_files()
File "/home/scjody/pwbank/src/hg/web-banking/lib/python2.6/site-packages/django/http/__init__.py", line 360, in _load_post_and_files
  self._post, self._files = self.parse_file_upload(self.META, data)
File "/home/scjody/pwbank/src/hg/web-banking/lib/python2.6/site-packages/django/http/__init__.py", line 317, in parse_file_upload
  warning = "You cannot alter upload handlers after the upload has been processed."
File "/home/scjody/pwbank/src/hg/web-banking/lib/python2.6/site-packages/django/http/__init__.py", line 302, in _set_upload_handlers
  raise AttributeError("You cannot set the upload handlers after the upload has been processed.")
AttributeError: You cannot set the upload handlers after the upload has been processed.

This is because of the way Piston works around Django's lack of PUT support: it sets request.method to POST, calls request._load_post_and_files(), and then sets request.method back to PUT. This works fine unless session_csrf is being used, in which case _load_post_and_files() fails with the error above.

I can't think of a good way to fix Piston. A fairly gross way to work around it in session_csrf is to do:

--- a/session_csrf/__init__.py
+++ b/session_csrf/__init__.py
@@ -87,7 +87,9 @@ class CsrfMiddleware(object):

         # Try to get the token from the POST and fall back to looking at the
         # X-CSRFTOKEN header.
-        user_token = request.POST.get('csrfmiddlewaretoken', '')
+        user_token = ''
+        if request.method == 'POST':
+            user_token = request.POST.get('csrfmiddlewaretoken', '')
         if user_token == '':
             user_token = request.META.get('HTTP_X_CSRFTOKEN', '')

This will prevent any request that sets a "csrfmiddlewaretoken" field in a PUT rather than using an X-CSRFToken header from passing CSRF checks, but that wasn't going to work anyway with the current session_csrf (it only checks POST, which will be empty.)

Given that Django's PUT support is lacking anyway - anyone doing a PUT is probably using Piston or Tastypie, which uses _load_post_and_files too - is this the best we can do, or can someone think of a better way?

Should I submit a pull request with this fix given that it's better than what session_csrf currently does?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant