Opened 3 years ago
Last modified 3 years ago
#33360 closed Bug
Add missing support for `Origin: null` (`CSRF_TRUSTED_ORIGINS`) — at Initial Version
Reported by: | Tomasz Wójcik | Owned by: | nobody |
---|---|---|---|
Component: | CSRF | Version: | 4.0 |
Severity: | Normal | Keywords: | origin, CSRF_TRUSTED_ORIGINS, null |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In Django 4, #16010 has been released. It includes 2 changes that affect my project:
- origins in
CSRF_TRUSTED_ORIGINS
are required to include an HTTP scheme Origin
header, if present in the request headers, will always be checked againstCSRF_TRUSTED_ORIGINS
The problem is that by default when the project is running on localhost, browsers will always send Origin: null
(correct me if I'm wrong).
if 'HTTP_ORIGIN' in request.META will always evaluate to True
on localhost, even if Origin: null
.
if request_origin in self.allowed_origins_exact will never evaluate to True
on localhost, as null
will never be a valid origin as it doesn't include a scheme.
As a result, it's impossible to POST a form on localhost.
- If it's a regression to 16010, I'd propose changing
if 'HTTP_ORIGIN' in request.META
to
if request.META.get('HTTP_ORIGIN') is not None
- If it's a feature, I'd suggest adding the above or a setting
CSRF_ALLOW_NULL_ORIGIN = False
but it'd require a change in all projects migrating to v 4
- if I am mistaken and the
Origin
header should be automatically populated by browsers with a non-null value when POSTing from localhost, this ticket can be closed (or maybe docs could be improved?)
Sample code that is failing on 4 and is working fine on 3.x
# settings from corsheaders.defaults import default_headers CORS_ALLOWED_ORIGINS = [ "http://localhost:8000", "http://127.0.0.1:8000", ] CSRF_TRUSTED_ORIGINS = [ "http://localhost:8000", "http://127.0.0.1:8000", ]
# template <form method="post"> {% csrf_token %} </form>
Error:
Origin checking failed - null does not match any trusted origins.
Request headers:
Host: localhost:8000 Origin: null
Even if I'm wrong, it's worth noting that the standard defines opaque origin
when Origin
will be set to null
so technically this value should be supported anyway but I don't understand its definition.
Let me know if there's something to do here. If yes, please assign me.