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.
Related
I'm developing a backend for a mobile app with Django where for user registration the user data are sent with the POST method. Since Django provide CSRF security as a middleware. Here my problem is if I have a front end I can enable CSRF token by jinja code as {% csrf_token %} but since it's a backend and how to resolve this problem
To guard against these type of attacks, you need to do two things:
1 Ensure that the 'safe' HTTP operations, such as GET, HEAD and OPTIONS cannot be used to alter any server-side state.
2 Ensure that any 'unsafe' HTTP operations, such as POST, PUT, PATCH and DELETE, always require a valid CSRF token.
If you're using SessionAuthentication you'll need to include valid CSRF tokens for any POST, PUT, PATCH or DELETE operations.
In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation.
Check this link. It explains exactly what your approach should be.
Basically you need to send csrf token in the header if you want the POST request to have csrf. But we do not ask for csrf tokens for non authenticated requests.
It would be better if you go with Django Rest Framework to create APIs if you aren’t already using it
One solution is to remove csrf token line form setting.py file :)
I am building an application after finishing up my website. Now, the backend for both of these should be common, but Django's csrf token is meant to be a security against this. Since I am not using a web browser, I am unable to get a csrf token cookie. At the same time, django will need it to access its APIs.
Is there any way I can get the cookie from Django and get it into React Native?
Not clear what you want to do. But if you are writing a native application, why don't you use a token identification mechanism?
There are lots of simple (and less simple solutions out there).
Assuming you are using django rest framework.
Simple built-in Token authentication
https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
Token, but with expiry and DB encryption
https://github.com/James1345/django-rest-knox
JWT
https://github.com/davesque/django-rest-framework-simplejwt
May I know your login URL? Use rest-auth login URL. Allauth URL gives Csrf issue.
We make react SPA with django-rest-framework on backend and use django-rest-auth for user authentication.
When user has logged in, we show him form for change profile data. When user submit this form, we take csrf token from cookie in login response, and put them in request X-CSRFToken header. Server responses that token is missing or incorrect.
If user refreshed the page, and repeated the same actions, csrf token is correct and profile data is updated.
How to solve this problem and why it occurs?
It looks like this is happening:
The login is successful
The cookie+token is created by the CSRF API and returned to the endpoint
The ready state executes some code not executed after the API response
The certificate is validated and the cookie+token is set in the database/app config/server-side cache during a GET request and/or by the ready state callback
Since there is no GET request until the refresh, the cookie+token is not centrally stored until then. Add a request to mimic what happens during the GET, then store it where it is currently being accessed for subsequent requests.
References
Issues with CSRF token and how to solve them | SAP Blogs
Why refresh CSRF token per form request? - Information Security Stack Exchange
CSRF Protection — Flask-WTF 0.14
CSRFGuard 3 Configuration - OWASP
Spring Security: Cross Site Request Forgery (CSRF)
Cross Site Request Forgery protection | Django documentation | Django
XSRF/CSRF Prevention in ASP.NET MVC and Web Pages | Microsoft Docs
Cross-Site Request Forgery is dead!
Still think you don't need HTTPS?
I am using Django + Django REST Framework + Django OAuth Toolkit.
I understand that AJAX calls from a web session require CSRF protection, but it is my understanding that mobile apps don’t as the very thing CSRF check are protecting against can’t happen in a dedicated app. If a person has an OAuth token, they are not using our web app so it seems I don’t need to perform CSRF checks in that case.
Is there any way to disable CSRF checks on REST Framework endpoints when a request includes an OAuth token, and if so is this a safe thing to do? Or should all requests be protected by the CSRF mechanism regardless?
You should probably be using DRF's token authentication with a mobile app. Initially, the user logs in to your backend with a username and password and then the backend issues a token for that instance of the mobile app, which [securely] stores the token locally. With token authentication and the reality of sending your credentials (over SSL/HTTPS) to the server on every request, you obviate the need for a CSRF check and thus no CSRF check is done.
I need to access a djangorestframework api but because the django server uses CSRF token and i cant get past it. How can i configure djangorestframework to override the djangorestframework and not be redirected to login?
Im new to this so i need help.
accessing the django rest framework would be a pure python program which runs in the background of a client pc collecting data so i need to use urllib2 or request for this. any ideas?
The API needs to expose an authentication method for your client to use.
The SessionAuthentication style requires CSRF validation and is suuitable for javascript based clients, running in the context of a logged-in application. If this describes the sort of client access you're making then read the Django documentation on CSRF and AJAX requests, which describes how to pass a CSRF token to a javascript based client.
Other schemes such as TokenAuthentication do not require CSRF validation, and will successfully authentication without passing any CSRF token.
Make sure that you know what schemes the API supports and choose the right one to use for your client access.
For more information see the authentication documentation.