#33360: Add missing support for `Origin: null` (`CSRF_TRUSTED_ORIGINS`)
-------------------------------------+-------------------------------------
               Reporter:  Tomasz     |          Owner:  nobody
  Wójcik                             |
                   Type:             |         Status:  new
  Uncategorized                      |
              Component:  CSRF       |        Version:  4.0
               Severity:  Normal     |       Keywords:
           Triage Stage:             |  origin,CSRF_TRUSTED_ORIGINS,null
  Unreviewed                         |      Has patch:  0
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 In Django 4, [https://code.djangoproject.com/ticket/16010 #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 against `CSRF_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).

 
[https://github.com/django/django/blob/2f73e5406d54cb8945e187eff302a3a3373350be/django/middleware/csrf.py#L433
 if 'HTTP_ORIGIN' in request.META] will always evaluate to `True` on
 localhost, even if `Origin: null`.
 
[https://github.com/django/django/blob/2f73e5406d54cb8945e187eff302a3a3373350be/django/middleware/csrf.py#L281
 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

 
[https://github.com/django/django/blob/2f73e5406d54cb8945e187eff302a3a3373350be/django/middleware/csrf.py#L433
 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.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33360>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/052.c20dc9af1127eb0a2ca6aa6653a75618%40djangoproject.com.

Reply via email to