POSTing data to a django view from a stand alone script with CSRF

90 views
Skip to first unread message

Larry Martell

unread,
Dec 5, 2014, 11:16:44 PM12/5/14
to django...@googlegroups.com
I have a django view that normally receives POSTed data from a web
page. That all works fine. But now we also want to call that view from
a python script. That is failing with a 403 because of a CSRF
mismatch. I can disable CSRF on my view and then it does work from the
script.

Is there some way I can have it work with CSRF with my script?

James Schneider

unread,
Dec 6, 2014, 1:41:44 AM12/6/14
to django...@googlegroups.com

Check out Collin's email from earlier, it has an example using curl but you should be able to adapt your web request with the cookie and POST values via the python script. The cookie and POST values for the CSRF token can be anything, they just need to match.

https://groups.google.com/d/msgid/django-users/fb6e54a8-c9e7-45f7-882f-bc05c8ee90d2%40googlegroups.com?utm_medium=email&utm_source=footer

-James

--
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...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACwCsY6tVsLCdNSwi0VnSx2JhGQew%2Be9fTU%2BadgT%2BdL%2BJFNFiw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Carl Meyer

unread,
Dec 6, 2014, 1:44:22 AM12/6/14
to django...@googlegroups.com
signature.asc

Torsten Bronger

unread,
Dec 7, 2014, 9:39:39 AM12/7/14
to django...@googlegroups.com
Hallöchen!
We make it like this (roughly, but you probably can fill the gaps
yourself):

class Connection(object):
cookie_jar = cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie_jar))
http_headers = [("X-requested-with", "XMLHttpRequest"),
("Accept", "application/json,text/html;q=0.9,application/xhtml+xml;q=0.9,text/*;q=0.8,*/*;q=0.7")]
opener.addheaders = http_headers

def do_http_request(self, url, data=None):
if data is None:
request = urllib.request.Request(url)
else:
# "Referer" is necessary for HTTPS communication.
headers = {"Content-Type": "application/x-www-form-urlencoded", "Referer": url}
request = urllib.request.Request(url, urllib.parse.urlencode(data), headers)
self.opener.open(request)

def set_csrf_header(self):
"""Copies the cookie to the header of the subsequent requests."""
csrf_cookies = {cookie for cookie in cookie_jar if cookie.name == "csrftoken"}
if csrf_cookies:
assert len(csrf_cookies) == 1
self.opener.addheaders = self.http_headers + [("X-CSRFToken", csrf_cookies.pop().value)]

def login(self, username, password):
# First, a GET request to get the CSRF cookie used only for the
# following POST request. (It's some sort of bootstrapping;
# only necessary for the very first request.)
self.do_http_request("http://mysite.com/login")
self.set_csrf_header()
self.do_http_request("http://mysite.com/login", {"username": username, "password": password})
# Now, set the CSRF token for the rest of the communication.
self.set_csrf_header()


Tschö,
Torsten.

--
Torsten Bronger Jabber ID: torsten...@jabber.rwth-aachen.de
or http://bronger-jmp.appspot.com

Larry Martell

unread,
Dec 8, 2014, 9:14:47 AM12/8/14
to django...@googlegroups.com
On Sat, Dec 6, 2014 at 1:41 AM, James Schneider <jrschn...@gmail.com> wrote:
> Check out Collin's email from earlier, it has an example using curl but you
> should be able to adapt your web request with the cookie and POST values via
> the python script. The cookie and POST values for the CSRF token can be
> anything, they just need to match.
>
> https://groups.google.com/d/msgid/django-users/fb6e54a8-c9e7-45f7-882f-bc05c8ee90d2%40googlegroups.com?utm_medium=email&utm_source=footer

Thanks. This is very simple. So simple I didn't even think of this.
But then can't anyone override the CSRF protection very easily?
> https://groups.google.com/d/msgid/django-users/CA%2Be%2BciWgYvFoXtC7PSKY-ijgpj82vHdkhJhrms4-0yEfk6KgWA%40mail.gmail.com.

Carl Meyer

unread,
Dec 8, 2014, 11:45:22 AM12/8/14
to django...@googlegroups.com
Hi Larry,

On 12/08/2014 07:14 AM, Larry Martell wrote:
> On Sat, Dec 6, 2014 at 1:41 AM, James Schneider <jrschn...@gmail.com> wrote:
>> Check out Collin's email from earlier, it has an example using curl but you
>> should be able to adapt your web request with the cookie and POST values via
>> the python script. The cookie and POST values for the CSRF token can be
>> anything, they just need to match.
>>
>> https://groups.google.com/d/msgid/django-users/fb6e54a8-c9e7-45f7-882f-bc05c8ee90d2%40googlegroups.com?utm_medium=email&utm_source=footer
>
> Thanks. This is very simple. So simple I didn't even think of this.
> But then can't anyone override the CSRF protection very easily?

This is explained in the link to a previous thread that I posted above.

The CSRF protection works because malicious JS can't control the value
of the CSRF cookie submitted by your browser.

Carl

signature.asc

Larry Martell

unread,
Dec 8, 2014, 11:51:56 AM12/8/14
to django...@googlegroups.com
Right, but anyone can write a script to bypass the CSRF protection. I
was surprised that it would be so easy to do that. I guess that's not
what CSRF was designed to protect against.

Carl Meyer

unread,
Dec 8, 2014, 12:04:46 PM12/8/14
to django...@googlegroups.com
On 12/08/2014 09:51 AM, Larry Martell wrote:
> Right, but anyone can write a script to bypass the CSRF protection. I
> was surprised that it would be so easy to do that. I guess that's not
> what CSRF was designed to protect against.

Right. There's no such thing as a CSRF attack via script. The definition
of a CSRF attack is that you trick a user's browser into doing something
the user didn't intend to do, taking advantage of the
session/authentication stored in their browser cookies.

Carl

signature.asc
Reply all
Reply to author
Forward
0 new messages