0

I have implemented a Django web app on AWS Fargate using Docker behind Application Load balancers.

When I try to log in to the web app I get the following:

Error 403 CSRF verification failed. Request aborted.

Environment: I am using Application Load Balancer (ALB) as per the best practices of AWS. The ALB also has a TLS certificate to properly handle HTTPS when I run multiple instances of the web app.

I tried to resolve the issue by forcing stickiness of the ALB targets assuming that the Round-Robin lands the requests on different servers. I also reduced the number of docker instances to one (so there is no Round-Robin).

None of this made any difference.

I managed to log in (to get CSRF to work well) was when I connected directly to a docker instance (no Load Balancer) and when I used only HTTP on the Application Load Balancer - disabling redirect to HTTPS. This leads me to believe that the issue is between the HTTPS part of the load balancer and the Django web app.

Disabling HTTPS is not production ready, so I am back at square one. I saw a similar question posted here, without answers: django posts receive CSRF verification failed after switching to load balancer

1 Answers1

1

After placing a debug on the live system as a temporary measure the underlying issue became clear.

Referer checking failed - https://test.domain.tld/path/ does not match any trusted origins.

The solution is through the CSRF_TRUSTED_ORIGINS parameter in Django. A quote from the Django documentation:

    CSRF_TRUSTED_ORIGINS
    Default: [] (Empty list)
    
    A list of hosts which are trusted origins for unsafe requests (e.g. POST). 
For a secure unsafe request, Django’s CSRF protection requires that the request have a Referer header that matches the origin present in the Host header. 
This prevents, for example, a POST request from subdomain.example.com from succeeding against api.example.com. 
If you need cross-origin unsafe requests over HTTPS, continuing the example, add "subdomain.example.com" to this list. 
The setting also supports subdomains, so you could add ".example.com", for example, to allow access from all subdomains of example.com.

A similar discussion and solution can be found in this thread. CSRF validation does not work on Django using HTTPS