Django CSRF in a cluster - python

Can someone example to me how CSRF works in the cluster setup?
I have a kubernetes cluster hosting a django website, and I'm having some occasional issues with 403 errors. I have multiple instances of the site load balanced in kubernetes.
How does CSRF work when a POST is sent from 1 instance and handled by another?
Does CSRF site work if the docker images are updated during the time the form is being filled out?
Thanks!

Can someone example to me how CSRF works in the cluster setup?
Exactly the same way it usually ought not to (CSRF is Cross Site Request Forgery, i.e. the attack). To protect against it, you hand out secret tokens to your clients which they must include with subsequent requests. Your backend must validate that the tokens are valid, applicable and were, in fact, issued by a trusted source. There's a few ways to do that bit:
You can use MACs for that (in which case you have something pretty close to JSON WebTokens).
You can save your tokens to some trusted store and query that store on subsequent requests.
That is pretty much all there is to it.
Since your CSRF protection emerges from the combination of choices you made above, how to make it work in a distributed setup also depends on the specific implementation of the CSRF protection scheme.
Going by the Django docs, the default way to do it uses a 'secret' which is reset every time a user logs in. That means if hitting a different server for two subsequent requests triggers a new log in, all old CSRF tokens are effectively invalidated. So based on that:
You need to adapt your Django project to make sure different instances can resume working with the same session, and a re-login is not triggered
All your Django instances need to be able to access the same per log-in secret, so that any one of them can validate a CSRF token issued by any other.

You should disable CSRF for every instance, and manage the CSRF security from the API Gateway

Related

Sharing authenticated users between Django and django-rest-framework in the same project

I have a Django project that will ultimately consist of three apps. Two of which will be "normal" Django apps, the third is a djangorestframework app. I also plan on creating a desktop client for the project at some point.
I want the rest app to be the only entity communicating with the database. Hence I use requests to communicate with the rest endpoints from the views of the "normal" Django apps and I will do the same for the desktop client. I want all apps to be accessible only for authenticated users, so I'm using Django's authentication backend.
My question is how to pass on the authenticated user/session from the pure Django apps to the rest endpoints when using requests in the views.
I managed to authenticate on the rest API using request's HTTPBasicAuth, but that requires me to have the user's password at hand in plain text. Sure, I could create a technical user to do these requests. But that would also mean that each and every request would need to go through authentication first and that doesn't feel like the best approach.
I have tried to extract the session cookie from the request object that is provided to the views and pass it on through requests.get, but did not manage to put it into the requests.get call the right way.
As of now, using requests and the established sessions looks like my best bet, especially since that will be the way the desktop client will do things, too. So I'm currently looking for the right way to provide requests.get with the session cookie, but I'm certainly open for better solutions.
You should use tokens.
Basically any kind of authentication out of your django project should be managed with secure tokens.
And yes, authentication check should happen everytime you send a request. To make it faster, you can store tokens in memory. (You can use redis or maybe even load your db on memory or ... ) but this is the right and common way to it. Even django does this check everytime using it's builtin functions.
DRF docs recommended some few packages to manage these tokens:
DRF: Third party packages
I used knox for many projects and it's pretty good.
Basically to authenticate your users over all of your projects or microservices, you have to take the token from user, set it as header or ... for your request to the main database or authentication project.
Most of the apps use token in headers which you can simply add to all of your requests calls:
Requests docs: Custom Headers

Safe way to have globally accessible JWT token in Django

There's a lot out there on how to issue JWT tokens to clients from Django, but I'm looking for a way to store a JWT token that is issued to the Django app for authentication against an external API.
The setup:
Django requests and receives token from external API. It is good for 24 hours.
Every time a client a makes a request, the app must make an authenticated call to the external API. Ideally, if 3 clients make 2 requests each, we should only need to request a single JWT.
24 hours later, a fourth client makes a request. Django sees that the token is invalid and requests a new one.
The problems here:
Requests from multiple clients should not each require their own token.
The token must be able to be changed (this rules out sticking it in the settings)
The token must be stored securely.
Ideas so far:
Stick in the database with a field listing the expiry time. This seems questionable from a security standpoint.
Implement some kind of in memory storage like this https://github.com/waveaccounting/dj-inmemorystorage . This seems like overkill.
Any suggestions as to a better way to do this?
The django cache was the way to go. See the above link for an example.

How to handle session and token based authentication simultaneously using middle ware in django?

I want to use both token and session based authentication in my application with the priority of token. I have created two portal with the same URL one is using session and other is using token. So when session is available in cookie then token based request goes failed with "CSRF Token is missing" error message.
One solution I have in my mind using middle-ware where I can make priority to token. If both are available in request then custom middle-ware will remove session related stuffs and keep only token related information and proceed.
If anyone has solution available for this problem then please post in answer?
Thanks in advance.
In my case I have written custom middle-ware to handle the situation.
1. When I am login using API and api path is **/api/accounts/login**. So when request comes on this url then I am removing sessionid and csrftoken both.
When HTTP_AUTHORIZATION is available in request, I remove the session and csrftoken.
Using above two removal situation can be handled in my case.
Thanks to everyone for helping.!!
Django middleware execute in order according to the MIDDLEWARE_CLASSES tuple.
You'll want to ensure your Token based authentication middleware is located after AuthenticationMiddleware in MIDDLEWARE_CLASSES.
The docs describe this approach in the context of RemoteUserMiddleware.

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

"Error validating verification code." when requesting access_token

I order to get access to the Facebook API on behalf of a user, one must get an OAuth access_token, the process is well documented (albeit it appears to be some undocumented requirements from FB) but from time to time I get this "Error validating verification code." when trying to exchange a validation code for an access_token.
There seems to be a lot of people having such trouble and most of the time the redirect_uri seems to be the issue, but here the redirect_uri is fine (it's exactly the same as the one passed to the auth dialog, ends with a slash and do not have funky characters or a trailing query string, I read almost all threads on SO about this issue and none of the proposed solutions did solve my problem)
What is the most intriguing is that when I check my logs, where I write the exact request url I use, and manually try it to get the access token, then it works. It is like the request is failing when the user logs in but works after some time.
So the fact that it is working after all seems to indicate that the request is fine but there is a problem on the Facebook side, like if there was some replication involved that did not complete between the time the auth dialog do it's thing and I try to exchange the code for a token.
I put in place a retry mechanism, hoping that the delay between two calls would be enough and the second call would succeed, but it doesn't work either.
Also, it's working most of the time and I cannot tell any difference between when it works and when it fails, only the user changes.
Any suggestion would be greatly appreciated.
I just bumped into this issue and solved it.
The issue was that I specified the redirect_uri in the oauth call to be http://apps.facebook.com/myapp/ instead of https://apps.facebook.com/myapp/ .
One thing that was kind of odd is that the exact same parameters worked if I entered them into the browser address field, but not as a server side request from the application.
It is possible on a per user basis to specify if you want to browse Facebook with or without HTTPS, so I recommend that you test with the setting at both modes when you test your authentication flow.

Categories

Resources