Security in AJAX POSTing

7 views
Skip to first unread message

Taylor

unread,
Dec 18, 2008, 5:20:36 PM12/18/08
to Django users
I'm working on a game in Django where the majority of the interaction
comes through clicks that run JavaScript methods that use jQuery's
$.post() to post data to a url. To protect against cheaters and bots,
I must ensure that every post is made by a logged-in user and protect
against cross-site scripting, and I certainly don't want any injection
attacks. I know Django has many protections against these built in,
but since most of my requests come through AJAX posts rather than URL
requests or form submissions, I was wondering what steps I need to
take to fully protect myself.

Specifically:

Each of my views use the @login_required decorator, is there anything
else I need to do to ensure that the user is logged in and active
(i.e. do I need to check user.is_active)?

As stated above, my data comes through AJAX posts made by jQuery. Is
this data automatically cleaned against SQL injection? If not, is
there something in Django that I can call to access its cleaning
ability? Or do I have to do it myself?

I remember reading that Django Forms (haha, I still want to call them
newforms.. good times) automatically prevent cross site request
forgery by including a hidden, random, token. Is there a way that I
can access this ability for my own prevention?

And of course: Are there any other possible security concerns you guys
can think of that I should know about and that will keep me up at
night?

If I can make a suggestion (although this is probably better for the
django-developers group), it would be really nice to have a document
that outlines all of the precautions you should take for security.

Thanks so much!

Taylor

bruno desthuilliers

unread,
Dec 18, 2008, 6:00:54 PM12/18/08
to Django users
On 18 déc, 23:20, Taylor <trfl...@gmail.com> wrote:
> I'm working on a game in Django where the majority of the interaction
> comes through clicks that run JavaScript methods that use jQuery's
> $.post() to post data to a url. To protect against cheaters and bots,
> I must ensure that every post is made by a logged-in user and protect
> against cross-site scripting, and I certainly don't want any injection
> attacks. I know Django has many protections against these built in,
> but since most of my requests come through AJAX posts rather than URL
> requests or form submissions, I was wondering what steps I need to
> take to fully protect myself.

Nothing more. From the server's POV, this makes absolutely no
difference - all it sees are HTTP requests, period.

anb

unread,
Dec 18, 2008, 9:08:49 PM12/18/08
to Django users
> Each of my views use the @login_required decorator, is there anything
> else I need to do to ensure that the user is logged in and active
> (i.e. do I need to check user.is_active)?


The meaning of is_active is an application decision. It's just a field
on the model, you can do whatever you want with it.


> As stated above, my data comes through AJAX posts made by jQuery.  Is
> this data automatically cleaned against SQL injection?  If not, is
> there something in Django that I can call to access its cleaning
> ability?  Or do I have to do it myself?


Whether it comes through AJAX or not doesn't matter. If you use
Django's ORM to do your queries, you're safe from SQL injection.


> I remember reading that Django Forms (haha, I still want to call them
> newforms.. good times) automatically prevent cross site request
> forgery by including a hidden, random, token. Is there a way that I
> can access this ability for my own prevention?


Check out the CSRF middleware. You probably want to render a token
into all your pages and have your AJAX requests include it.

Andrew

Taylor

unread,
Dec 18, 2008, 10:17:32 PM12/18/08
to Django users
Yay!! Now I can sleep tonight!

So the docs say this about the CSRF middleware: "It may still be
possible to use the middleware, provided you can find some way to get
the CSRF token and ensure that is included when your form is
submitted."

Has anyone found that way, or can anyone point me in the right
direction? Or do I need to figure this out myself.

Thanks folks!

Taylor

Srdjan Popovic

unread,
Dec 19, 2008, 5:47:46 AM12/19/08
to Django users
Taylor,

If you are worried about POST data submitted through Ajax request
coming from another site, you should remember that browsers do not
allow XMLHttpRequest to be sent to other domains. Having said that,
you can still use the CSRF middleware for your non-Ajax requests. A
couple of paragraphs above the one you quoted you can read this:

"The middleware tries to be smart about requests that come in via
AJAX. Many JavaScript toolkits send an "X-Requested-With:
XMLHttpRequest" HTTP header; these requests are detected and
automatically not handled by this middleware. We can do this safely
because, in the context of a browser, the header can only be added by
using XMLHttpRequest, and browsers already implement a same-domain
policy for XMLHttpRequest. (Note that this is not secure if you don't
trust content within the same domain or subdomains.)"

This is as safe as non-SSL security can be.

I hope this helps.

Taylor

unread,
Dec 19, 2008, 9:13:17 AM12/19/08
to Django users
Oh awesome! I didn't know that, and yes it helps a lot!

I suppose I could compliment this with the request.is_ajax() and I'm
all set.

Thanks again!

Taylor

On Dec 19, 5:47 am, Srdjan Popovic <spopo...@bortolete-popovic.com>
wrote:
Reply all
Reply to author
Forward
0 new messages