403 Forbidden due to CSRF validation failing on client domains

Context: our app runs on myapp.com behind a proxy running on proxy.myapp.com.

We plan on allow users owning a domain (e.g. johndoe.com) to create a CNAME and point it to proxy.myapp.com and then link their profile on our site to that domain. The domain name is registered in our database. Basically their domain just acts as an alias of our site.

Custom middleware we introduced checks host names against the database to disallow domains that are making a request to our proxy but don’t exist in our system. I guess you could say this already provides CSRF protection of some kind.

Anyway, I digress. Everything was working perfectly in my development environment, I set up some local domains and tested out that they could indeed be used as aliases for the main site.

However I stumbled on a problem in the staging environment. POST requests made from custom domains we own (e.g. somedomainweown.com) were responding with 403 Forbidden due to CSRF validation failure. Note that these are plain http requests, not secure (still looking into how to do this for dynamic domains).

Basically, unless a request is made by staging.myapp.com, CSRF validation will fail. Even proxy.staging.myapp.com fails, and any other domain as I mentioned.

What are my options here?

It is not clear enough what you mean by “a proxy running on proxy.myapp.com”. Is it a web app which takes requests and passes them on? A front-end webserver? More importantly, when cookies are sent to this proxy, do they reach your main server?

When you say “domains are making requests”, please use more accurate language – is the request coming from the other servers or from browsers looking at pages from these domains?

Generally speaking, CSRF protection is of very limited value where Man-in-the-Middle attacks are possible, and some of the checks in Django’s code reflect this. You would be much better off testing on https as soon as possible.

Forgive my terminology but I am not experienced enough with server administration to be absolutely proper or to even understand what’s going on under the hood and convey this to you.

It is not clear enough what you mean by “a proxy running on proxy.myapp.com”. Is it a web app which takes requests and passes them on? A front-end webserver? More importantly, when cookies are sent to this proxy, do they reach your main server?

With this I meant we have 2 server blocks in our nginx configuration. The proxy.myapp.com one has a proxy_pass directive to myapp.com, and the myapp.com server block has the Django app (gunicorn socket). I have no idea if cookies sent to the proxy reach the main server. The issue itself never crossed my mind. Why wouldn’t they? How can I tell if they do?

When you say “domains are making requests”, please use more accurate language – is the request coming from the other servers or from browsers looking at pages from these domains?

You own mydomain.org and create a CNAME to point to proxy.myapp.com and register it in your profile settings in our site. When you try to log in to mydomain.org you’re getting a CSRF validation failure.

This is effectively what happens in the staging server. staging.myapp.com works just fine (this one does have https) but trying to log in to proxy.staging.myapp.com or any other custom domain we set up for testing purposes (e.g a real domain we own, like firstnamelastname.com - just imagine this address exists) just returns a 403 response because of CSRF.