Django: Set crsf token while making POST request from rest client - django

I'm using the chrome rest client to test the api calls.
A GET request is working fine but while making a POST request , getting 403 hidden response.
description is
CSRF verification failed. Request aborted
I'm setting as Content-Type=application/json.
One way would be to use #csrf_extempt, but seems to be good choice.
How to resolve above issue ?

Using #csrf_extempt is infact a good practice when you are providing an API to your site. Cross-site request forgery is what csrf is but in your case it won't be a forgery since an api can(should) be called from any site but yours.
.
Moreover sharing csrf token will prove to be very tricky.

In thre request, include an X-CSRFToken header with the CSRF token value obtained from the csrftoken cookie.

Related

What it the meaning of csrf token?

I am getting this error please haldle the csrf token in django project.When I first made an AJAX call with a POST request, I got a HTTP 403 Forbidden error. A quick debug led me to the CSRF authorisation problem. The backend refused to authorise the request because there is no accompanying CSRF token to prove that the request is not from a foreign site.
From the documentation:
"The CSRF middleware and template tag provides easy-to-use
protection against Cross Site Request Forgeries. This type of attack occurs when a malicious website contains a link, a form button
or some JavaScript that is intended to perform some action on your
website, using the credentials of a logged-in user who visits the
malicious site in their browser."
Therefore, when making a POST request, you should always include a CSRF token.
For more information, including how to use it with AJAX calls, please refer to the documentation:
https://docs.djangoproject.com/en/3.0/ref/csrf/

Django DRF with React: How to obtain CSRF cookie?

I have a React frontend running at frontend.example.com and a Django backend with DRF running at backend.example.com. I am using Django Session Authentication and I want to properly implement CSRF protection.
Taking the React login page frontend.example.com/login as an example. It's the first time for a user to visit the page. There is a form with a user and password and on submit a new POST request is created to the Django backend. To the best of my knowledge, the CSRF token cookie should already be included in this request, right?
How to obtain that CSRF token from the Django backend? I am thinking of doing a GET request to the Django backend on loading the login-page to obtain that CSRF token cookie. Is that the way to do it or is there any other best practice?
Django has a section for AJAX request and how to handle CSRF: AJAX
Using this method you should send the token over and over again for each post request. The other method is using CORS. in this method, you only respond to the domains that you already whitelisted with headers that are whitelisted as well. So, instead of getting and passing CSRF token, you check if the request is coming from the right domain and then you can respond to it. And combining with a token system for user authentication, you should be good.
You can use this package for handling CORS if you use DRF: django-cors-headers
Using rate limiting can also help you avoid spams and robots to do noticeable harm.

Sending CSRF Tokens via Postman

I'm trying to test my web server's login with Postman. First, I send a GET request to my login url, and I get a CSRF token as a cookie. Then, I make a POST request to that login page, with my username, password, and CSRF token.
My problem is, when I do this in Postman, I get a 403 forbidden error when I try to make that POST request to login. I'm copying the CSRF token received and putting it as one of the POST parameters, and I'm using a valid username and password. Is there anything I'm overlooking here?
You need to set it as a header in the request, not in the body. X-CSRFToken is the key and the value is CSRF token from the cookie. This will work if you are using an API framework like Tastypie or Django Rest Framework.
If you are authenticating without an API layer you would need to actually attach the cookie or create one with the CSRF token. This post explains it.
Try installing the Postman Interceptor Extension on GoogleChrome. It worked for me.
Works for me :
Set in Postman Header :
KEY : Authorization
Value : Token "Your token"

CSRF verification failed on authorization

When I'm trying to authorize by
curl -X POST -d "grant_type=password&username=myusername&password=mypassword" http://localhost:8000/oauth2/authorize/
I get 403 forbidden: CSRF validation failed. Request aborted. I can't understand why, any help would be appreciated.
By the way I use Django OAuth Toolkit for authentication.
Edit: I know about CSRF protection and how to use it in django view and forms, I'm using a package called Django OAuth Toolkit for oauth 2 authorization which shouldn't ask for csrf token. There is a little information here about what I'm tring to achieve.
I'm ashamed to say that I was sending the request to wrong url, I should have sent it to http://localhost:8000/oauth2/token/
curl -X POST -d "grant_type=password&username=myusername&password=mypassword&client_id=myclientid" http://localhost:8000/oauth2/token/
You need to add csrf token in your POST data.
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
It's probably worth your while reading the documentation on Django's built in Cross Site Request Forgery protection.
Any post to a Django view will need the csrfmiddlewaretoken set, otherwise you'll get a 403. You'll need to either include it, or exempt your view from CSRF protection (prefer the former approach if possible).

CSRF protection in Django

I don't get one thing about CSRF protection in django. For example we have some malicious site. What is the problem to send get-request from this site to csrf protected url, parse the page and get csrf value, then post with this value?
For example we have some malicious site. What is the problem to send
get-request from this site to csrf protected url, parse the page and
get csrf value, then post with this value?
If you do this, the session counterpart of the CSRF cookie will not match, and your request will be rejected.
Also, it should be noted that referrer check is done only for HTTPS requests to prevent a MitM vulnerability.
See this django wiki entry for a discussion on how CSRF protection works, and this SO question that discusses the MitM attack specifically.
The main purpose of Django's CSRF is explained in the Django Docs (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-it-works):
This ensures that only forms that have originated from your Web site
can be used to POST data back.
So it checks several things - cookie, referrer, posted value. And there are some limitations, that you cannot always modify all these values at your will. For example - you can set X-CSRFToken token and the POST value in an AJAX call, but the browser will not allow you to override the referrer header... You might succeed to do a successful POST using urllib2 or similar library, but this is not covered by the CSRF protection, as it is the same as you POST on a page.
Again - CSRF means Cross Site Request Forgery and it is what it protects.
REFERRER will be checked. If the REFERRER does correspond to correct URL then POSTing data is not valid.