﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
34855	Document CSRF_TRUSTED_ORIGINS relation to SECURE_PROXY_SSL_HEADER.	jeroenmuller	nobody	"When the CSRF origin check fails, the documentation points in the direction of adding that origin to CSRF_ALLOWED_ORIGINS. However, as far as I understand this should only be neccessary if there are actually cross-origin requests. In practice the CSRF origin check may also fail when is proxying HTTPS traffic over HTTP without setting up SECURE_PROXY_SSL_HEADER accordingly. This problem may occur suddenly when upgrading to Django 4.0, because this version turns on the origin verification in the CSRF middleware. In that case the Django release notes point in the direction of adding the failing origin to CSRF_ALLOWED_ORIGINS: https://docs.djangoproject.com/en/4.2/releases/4.0/#csrf-trusted-origins-changes-4-0. But this is not the optimal solution, and may weaken CSRF protection if a user ends up just adding a pattern matching all subdomains or the complete ALLOWED_HOSTS lists to CSRF_ALLOWED_ORIGINS. 

It might be useful to add a note or warning below https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS explaining that it should only be neccessary to configure this if you are actually making requests across subdomains, and in other cases setting up SECURE_PROXY_SSL_HEADER might be a more appropriate solution (as long as the proxy correctly sets a header like X-Forwarded-Proto). 

I ran into this problem when I updated a project hosted behind AWS ELB load balancer and gunicorn to Django 4.0, and the CSRF origin checking for the Django admin stopped working in a staging environment, with the message `CSRF verification failed. Request aborted.`. I could not figure out what was going on using the documentation and ended up finding the root cause through a stackoverflow answer which pointed out that the origin header is compared against a string constructed of the host, prefixed by either http or https based on the result of ''request.is_secure()''

 - https://stackoverflow.com/a/71482883

In my case, the proxy setup was forwarding requests over HTTP, so is_secure() was false and CSRF was comparing the origin `https://subdomain.my-domain.com` against ""host"" `http://subdomain.my-domain.com`. It seems like the best solution here is to use  SECURE_PROXY_SSL_HEADER to allow Django to determine if the client is using HTTPS or not, and use the ""host"" string `https://subdomain.my-domain.com` . Looking at the referenced stackoverflow thread, this is a recurring problem for users updating to Django 4.0 and many end up with the sub-optimal solution of adding the origin with https to CSRF_ALLOWED_ORIGINS explicitly."	Cleanup/optimization	closed	Documentation	4.2	Normal	wontfix	CSRF	Florian Apolloner	Unreviewed	0	0	0	0	0	0
