Django and CSRF protection for mobile apps - django

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.

Related

How to set up javascript and django applications to exchange jwt tokens

I have a SAP implemented on the Netlify platform. The processing for the app is implemented in a django api running on a hosted server.
Users are authenticated on the Netlify app, but do not need to be authenticated in django.
I now want authorised users to be able to post data to the api and the django server objects with the message
Forbidden (CSRF cookie not set.): /api/save-archive/{...}/
I am looking at implementing JWT cookies and have considered djangorestframework_simplejwt but that seems to require that the user is authenticated in django
My question is, what software elements do I need to be able to generate and consume a token is this scenario?

How protect from CSRF Login and Register endpoints (views) of an API created with DRF which use JWT as authentication?

I have been searching and reading other questions and blogs, but I didn't find anything concrete about my doubt.
A little of context:
I am developing a SPA which works with a REST API in Django by means of Django Rest Framework (DRF) and the authentication is made it through Bearer token: JWT (package 'Simple JWT'). So, I was reading whether it needs protection against CSRF:
• Do I need CSRF token if I'm using Bearer JWT?
• Should I use CSRF protection on Rest API endpoints?
• The Web API Authentication guide, Bearer tokens
Basically if the browser does not make an automatically authentication (with sessions or some kind of cookie), the odds of a CSRF vulnerability are slim. This approach is achieved with the Bearer Tokens using the JWT inside the 'Authorization' header.
Updated: In this developing stage it is setted Django-CORS, but in production it will be configured a proxy through Nginx. Avoiding CORS attacks.
The problem:
There are some public endpoints, that don't need authentication, so I used this permission in DRF settings
'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticatedOrReadOnly'],
This way, unauthorized users only can make safe requests -methods: GET, HEAD and OPTIONS-. The users, with a JWT, can perform any kind of request.
Login and register views works through POST requests due to modify the state of the application. The issue is the above permission avoids that the 'anonymous' (to call it in somehow) user from being able to register or login. The question is, how do I protect them?
I have thought in maybe change the permission to these views to 'AllowAny'. But I don't know if this returns the concern about CSRF, because there is no Bearer token here, or perhaps other security vulnerabilities that I can't even imagine.
Another possibility is to only use the CSRF token in these views.
Or is there any better approach to protect these two endpoints?
I hope someone will be able to help me!
You can use CSRF tokens in your login and registration forms, and this will sufficiently protect you from CSRF attacks against these endpoints. You would then have to obviously allow for anonymous access to these endpoints. It's usual that login and registration endpoints are not behind a firewall and are accessible to anonymous users.

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.

Secure authentication between ReactJS and Django

Been reading and watching quite a bit, and asking a lot of questions regarding ReactJS and Django.
This particularly helped me to understand the the flow of data from Django REST Framework to ReactJS and from ReactJS to Django REST Framework.
Django Forms and Authentication with Front-end Framework (AngularJS/ReactJS)
However, the one thing I am trying to understand is authentication to the Django REST Framework. I understand from the documentation that it has built in authentication. Since this is sensitive data, I would obviously want it protected people retrieving it just by going to http://www.my_site.com/info/api.
I would need to setup ReactJS to be the only thing that can request data from the API whether that is through a key or username/password credentials. I am just curious how this is handled? Obviously I don't want that hard coded in ReactJS because it will compile with the rest of ReactJS.
Here's how I'd approach it: I'd use a JSON Web Token (JWT) for authentication and authorization.
You'd use your back-end to protect ALL API requests from invalid JWT's except for routes where a user won't have a token (ie, registration/log-in pages).
Here's how the flow of the application will go:
A new user registers to your app with standard credentials such as email and password.
Your back-end will create a new user, sign a new JWT token (usually with the user's ID). You'll probably use a third-party library to sign/verify tokens (I don't have experience in the Django community but I am sure a quick Google search will give you answers). Your back-end will send back this token. This is the only time the back-end will receive email, passwords or any other sensitive information on registration.
From this point on React will only use this token for authorization. React will save this token somewhere (ie, localStorage) and send this token along with the other parts of a request to the API routes you created with your back-end. You'll send this token in the authorization headers in the request.
Your back-end will validate this token using a third-party library. If it's invalid the request stops and an unauthorized error is returned. If it's valid the request continues.
This achieves the following:
Your API routes are protected against unauthenticated users
Each request to your API is verified for authorized users which protects anyone from requesting any part of your API.
You can further solidify this by only allowing requests for users to modify their own data. For example, protect Suzy's profile from being modified by people other than herself by only allowing her token with her ID to modify her account/data.
Important Note- Your backend will never save these tokens in storage. It will verify the token on each request. Read more about JSON Web Tokens (JWT) and how it works.
Django Rest Framework has built-in token authentication and a third party package for JWT Token Auth.
If you the standard token auth would work for you, then it could be pretty simple with drf-redux-auth. If you need JWT for some reason, as suggested by Keith above, you could easily fork the above...

Overriding django authentication with Django rest framework authentication

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.