Django REST API set allowed hosts for individual endpoints - django

I would like to have different values for ALLOWED_HOSTS for different Django REST API endpoints. Is this possible? Here are more details:
I have a setup consisting of a Django REST API backend, a React frontend, a Postgresdb and nginx, each running in a docker container, managed by docker compose. I am exposing Django API endpoints that are accessed by the frontend from the user's browser, so I am adding the domain of the frontend to allowed hosts. However, I have one specific API endpoint that should only accept requests from the frontend docker container but never accept requests from outside. It should only be used for communication between the frontend and the backend container. So in this case i would have to restrict allowed hosts to the ip of the docker container. Both settings are possible and working, but I can only choose one of both in the global Django settings. My question is: Is it possible to set allowed hosts for an individual endpoint/url?
I suppose if there is no clean way of doing it I could run a manual check using HttpRequest.get_host() to verify the request host against the container name?

It's certainly possible.
In a pure Django context, I'd implement this as a Django middleware that intercepts the request, looks at the path and the request host, source IP and does what it needs to.
In a Django REST Framework context, I'd implement this as an additional authentication class, since it will then have access to the Django REST Framework context if required.
Finally, I'd recommend also protecting this "secret" endpoint with additional authentication – the simplest might be an additional secret header (X-Nik-Secret: very? ;-) ) that is known to the frontend container. That check can similarly be implemented in middleware or authentication.

Related

Accept only authentificated requests to backend

I have this question. I am quite new in this area.
I have web app.
This consist of services deployed on Docker engine.
The main services/containers are:
Frontend : React on Nginx web server
Backend (API) : Django, DRF on gunicorn on Nginx
For frontend I use Auth0 provider. It works as expected. If user is not authenticated/authorized it is redirected to login page.
Now I want also to "secure" my backend that it only would accept authenticated connections from frontend.
For backend (Django) I also have CORS enabled (django-cors-headers package), but I still can connect from my browser my-site/api/ and get the response.
Does anybody know which strategy should I use.
Should I somehow secure it using JWT tokens. Somehow pass it to backend in my request?
There is various ways of authorizing API calls from your front-end applications to execute actions on your back-end. These will tend to vary in a few aspects:
Complexity
Needing to know who sent the request
Access surfaces
Duration of access
Roles
and so on...
In this case if you have authenticated users on your front-end using AuthO then a JWT could make sense since using this method you can encode specific user data that will allow you to make the decision on your backend as to if that user should have access to that action at that time.
Here is an article explaining a few popular methods of authentication

Is there a way to restrict an API on a public webserver to a specific frontend?

My web application has a public API endpoint eg https://example-backend/home.
I have two frontends one for internal admin (https://example-admin.com) and the other for customers (https://example.com) both using the same backend endpoint.
The goal is to allow this API to only be available to the internal admin frontend.
I thought about using the HTTP ORIGIN header which would contain the frontend URL. Is that a good approach?
I think you need to check this:
Django allowed hosts

Which is the best way to protect a Django API?

I've deployed a Django API powered with Django Rest Framework with some open endpoints and some Authenticated endpoints using Token authentication.
Which is the best way to protect the entry API allowing only to send request from the app frontend team?
I was thinking to use an Nginx basic auth, but then the Authorization header is duplicated, so Token auth is not working.
You could filter the access in your API by filtering the IP address in case that the frontend team uses a static one (e.g. ALLOWED HOSTS).
Moreover, you could add the users of the frontend team in a specific group or provided the same role and filter the access by implementing a reusable custom DRF permission.
An other option could be the usage of a custom HTTP header or an API key (e.g. X-API-KEY header).

Only allow calls to endpoint from frontend Django Rest Framework

I am new to Django Rest Framework. My API is used in 2 ways:
I have a React frontend
As a normal REST API returning JSON
However, I don't want the endpoints called for my frontend to be able to be called in the normal REST API. Specifically, I want those endpoints to only be able to be reached when called from my frontend React app. How can I do this? Thanks!
I am not mistaken you are asking for host restrictions means your endpoint can only be called from a specific host than do just add your host cors whitelist. You can configure it using django cors header package

Best security practices for React + Django

I'm currently working on a project that uses Django API server and a NodeJS server running React. In development we're running Django on port 8000 and NodeJS on port 8080, and currently React is responsible for rendering the page and interacting with Django API, which provides data for React. In order for React to call Django APIs, we've enabled CORS in Django since they're on different ports.
My question is the following:
Is it safe to allow all CORS in production?
If not using the templates system by Django, is the site still protected against CSRF by defaults? If not, how to prevent CSRF in such settings (React+Django)?
Yes, it's safe to use CORS in production if you allow it for the correct origin domains. For example, if you are using django-cors-headers, use CORS_ORIGIN_ALLOW_ALL=False and a set of domains for CORS_ORIGIN_WHITELIST.
As the answers to this question explain, DRF uses CSRF tokens if using SessionAuthentication. However, if you are using other authentication mechanism (for example, token authentication or JWT) you are however also protected by the client browser not allowing unsecure requests from untrusted origins, i.e. not in your CORS_ORIGIN_WHITELIST. See answers to this question regarding security of CORS vs. CSRF token to prevent CSRF in general.