Bypassing Django CSRF Protection using external POST Request - python

I have a Python program that needs to be able to send data to my website (built with Django). This data will then be taken and displayed on a certain part of the website. The problem I'm having is that the CSRF protection built into Django blocks my POST request. From what I understand, this is usually avoided by adding {%csrf_token} to whatever form the POST request is being sent to. My problem is that I'm trying to send the POST request to a .cgi script rather than a form. Does anybody know how I could bypass the CSRF protection (preferably without removing it completely although this is an option.)

You should use the csrf_exempt decorator to avoid csrf protection in certains view.
You can read the docs for more information

In case you are using class based views, I'd recommend django-braces which uses a mixin to achieve this, as well as providing other extremely useful mixins.

Related

React JS Frontend with DRF backend authentication

Have developed a pretty decent API utilizing Django and Django Rest Framework to make my data available for consumption. Decided to build a React JS front end to be a little more dynamic than the standard Django templates. I have numerous views within DRF which work fine, I'm able to make calls against them and get or post to them no problem. Currently I'm working on implementing a login capability for the React frontend so that users will be given access to a couple protected views and will be presented with information relevant to them.
Maybe I'm not understanding what is supposed to be happening, web development isn't exactly my area of expertise. Have referenced the Django documentation a bunch trying to understand sessions and session authentication. I have a 'login' view which is taking a username and password provided to it, searching for a related 'User' record based off of the username and attempting to leverage the django.contrib.auth login method; this all seems to be working, the user is getting authenticated. After this step, I'm pretty much completely lost as to what is supposed to happen.
In my React component, I've attempted sending the username as a 'session' attribute in the header, I've tried including the csrftoken in the headers, I've tried to just enable 'withCredentials' in the callout. Really not sure what I'm supposed to be doing here. Is my login view supposed to be returning some attribute that I would then store in the react components to include in calls to protected views?
Been stuck on this for a while and am getting lost in reading documentation.
Thanks

How is Flask-Login's request_loader related to user_loader?

I apologize in advance for asking a rather cryptic question. However, I did not understand it despite going through a lot of material. It would be great if you could shed some light on this.
What is the purpose of a request_loader in flask-login? How does it interact with the user_loader decorator?
If I am using a token based authentication system (I am planning on sending the token to my angularJS front end, storing the token there and sending that token in the authorization-token header), will I need a request_loader or will a user_loader (where I check the auth header and see if the user exists) suffice?
From the Flask-Login documentation:
Sometimes you want to login users without using cookies, such as using
header values or an api key passed as a query argument. In these cases,
you should use the request_loader callback. This callback should
behave the same as your user_loader callback, except that it accepts
the Flask request instead of a user_id.
So, to answer your question, they both serve the same function for Flask-Login. They are both used to load the user. request_loader, however, is appropriate for custom logins.
Here's a great tutorial I found that utilizes request_loader to take advantage of token based authentication (The post is not my own, I'm merely sharing the link): http://gouthamanbalaraman.com/blog/minimal-flask-login-example.html
I need to make this clear.
This is the reason why you shoud use request_loader with flask_login.
There will be a lot of #login_required from flask_login used in your api to guard the request access.
You need to make a request to pass the check of auth.
And there will be a lot of current_user imported from flask_login,
Your app need to use them to let the request act as the identity of the current_user.
There are two ways to achieve the above with flask_login.
Using user_loader makes the request to be OK for #login_required.
It is often used for UI logins from browser.
It will store session cookies to the browser and use them to auth later.
So you need to login only once and the session will keep for a time.
Using request_loader will also be OK with #login_required.
But it is often used with api_key or basic auth.
For example used by other apps to interact with your flask app.
There will be no session cookies,
so you need to provide the auth info every time you send request.
With both user_loader and request_loader,
now you got 2 ways of auth for the same api,
protected by #login_required,
and with current_user usable,
which is really smart.
To verify users with Flask-Login's session_id for frontend requests through Angular, you must set the withCredentials configuration flag to true.
That is, if you are using Angular's $http.post(url,data [,config]) or $http.get(url [,config]), make sure the config object contains the property withCredentials set to true. This will instruct the browser to use its cookies in the same way it would for a full-on page visit.
For example,
$http.post('/api/login',{username:'myusername',password:'mypassword'},{withCredentials:true})
will post the data {username:'myusername',password:'mypassword'} to your site/app's /api/login route and, if you're using Flask-Login and are logged in, Flask will know.
You can set this behavior for all $http service requests by setting
$httpProvider.defaults.withCredentials=true
somewhere in your app. Currently, I have that line of code in my app.config block, which seems appropriate to me:
var myApp = angular.module('myApp');
myApp.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
});
(Since this post is about Flask, folks may want to send form data through Angular in such a way that it can be found in request.form, which has a similar solution, fyi.)

django csrf in mobile apps

I am developing a Android application, use django1.6 in server side,
I want to POST some data to the server. But its shows error 403.
What I have to do to overcome the error(CSRF token missing or incorrect)?
Is it a good idea to remove csrf middleware
(removing django.middleware.csrf.CsrfViewMiddleware from setting file)?
If not, what is an alternate solution=
This problem is not django specific. If you search CSRF Restful you will find many questions and answers about this. for e.g. this one
At the basic level, I would say that CSRF is a mechanism to plug security issues affecting people who use browsers. As such, people who use mobile applications are not likely to be affected by this.
You should keep the CSRF layer for people who access your application from web browsers and create a different scheme to access your api from other types of clients.
Yep, it's good idea, 'cose you just don't need it for mobile backend,
but just removing
'django.middleware.csrf.CsrfViewMiddleware'
won't be enough, you need add you own middleware, that will disable CSRF.
Here solution http://www.soyoucode.com/2011/really-disable-csrf-django

django dev server unread POST data will error

I have the solution, this is more of a Why question. The problem is when running a django dev server, when i make an ajax POST request with data, if the view never looks at the POST dict, i get a urllib2 exception. "a connection was forcibly closed by a remote host" or something.
If theres no post data, it returns fine, if the data is read, not even stored, a simple
request.POST
will return ok as well. Why is this?
Thanks
I'm guessing you're not sending the csrfmiddleware_token on your post request. It's a prevention mechanism for CSRF attacks and needs to be set on all POST messages. See the documentation for details.
You need to disable CSRF protection for that view function as it is enabled by default (the CSRF Middleware).
You can opt to disable CSRF protection via two ways:
Remove the CSRF middleware and use the #csrf_protect decorator on
view functions that you wish to use the CSRF protection. Use this if you generally don't
need CSRF (eg. no forms for most of the pages). See https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#the-decorator-method
Use the #csrf_exempt decorator on the view you wish to exempt the CSRF protection from.
This is useful when you only have a few view functions that does not require CSRF
protection. See https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#exceptions

Pyjamas + Django => CSRF confusion, 403 errors

I've got Pyjamas and Django running via Apache2 with mod_wsgi on Windows 7. I do not believe I'm getting issues from the setups of these things, though: the only thing that is not working is trying to POST information from Pyjamas-generated forms. Trying to use Pyjamas-generated forms in my application produces 403s (the "CSRF verification failed" error page).
I have spent hours on this and read all of the answers I could find on here related to CSRF and Pyjamas, and done a lot of external research just on CSRF and Django, Django and Ajax, etc. If this question isn't reaching anyone who has knows just what to do in this situation, I think I've whittled down the essence of the question.
How would one get the {% csrf_token %} into the Pyjamas-generated form? It seems like it might be impossible, because from what I understand CSRF tokens are not persistent, which a Pyjamas-generated page is ... My Pyjamas page is generated from a Pyjamas .py file, resulting in a folder full of hard-coded stuff. How is it that I would integrate the current CSRF token into that already-coded form?
Please don't hesitate to ask for more details, this issue has been incredibly hard to navigate. None of the published information on integrating Pyjamas & Django regards this; and the only solutions I've found that seem aware of CSRF in Django say you should probably just disable CSRF protection (which I could do, but what protection could I put in place of it? My own cookie system? Is it a terrible idea to disable CSRF protection in any case?).
Thank you!
You'll need to write some JavaScript to get the CSRF token from the cookie (part of the HTTP request), then add it to the form on submit.
Look at this answer for a starting point: Django CSRF check failing with an Ajax POST request
The key here is that the JavaScript can be as persistent as your Pyjamas-generated files, because they defer handling the token until the form is submitted.

Categories

Resources