#37025: Deprecate the prefixing of HTTP_ to header names in
RemoteUserMiddleware.aprocess_request()
-----------------------------+----------------------------------------
     Reporter:  Jacob Walls  |                     Type:  Bug
       Status:  new          |                Component:  contrib.auth
      Version:  5.2          |                 Severity:  Normal
     Keywords:               |             Triage Stage:  Unreviewed
    Has patch:  0            |      Needs documentation:  0
  Needs tests:  0            |  Patch needs improvement:  0
Easy pickings:  0            |                    UI/UX:  0
-----------------------------+----------------------------------------
 When Django 5.2 added an async path to `RemoteUserMiddleware` (#35303), it
 prefixed `HTTP_` to the provided (or default) header name before looking
 it up in `request.META`.

 I figure this was so that the default `REMOTE_USER` header would work out
 of the box. (For WSGI compatibility, `ASGIRequest` maps all user provided
 headers to `HTTP_`... variants.)

 This has two problematic effects:
 - It becomes tortured to document the security considerations, see recent
 change in #36862:

 > Under WSGI, this warning doesn’t apply to RemoteUserMiddleware in its
 default configuration with header = "REMOTE_USER", since a key that
 doesn’t start with HTTP_ in request.META can only be set by your WSGI
 server, not directly from an HTTP request header. This warning does apply
 by default on ASGI, because in the async path, the middleware prepends
 HTTP_ to the defined header name before looking it up in request.META.

 Notice how an implementation detail is leaking into an admonition, making
 it harder to reason about what's potentially user-controlled (wait, under
 ASGI, this other stuff is user-controlled, too!)

 - Custom headers can't be supplied in a way that works with both WSGI &
 ASGI:

 If you try to do this the "right" way, and define `HTTP_MY_CUSTOM_HEADER`
 as the header attribute, then `aprocess_request()` will lookup
 `HTTP_HTTP_MY_CUSTOM_HEADER`. Forcing the 'wrong' version
 (`CUSTOM_HEADER`) works on ASGI but breaks on WSGI, because no WSGI server
 will set that.

 ----
 I'm suggesting we should deprecate the current support for custom headers
 without "HTTP_" prefixes in the async path (`aprocess_request`) and remove
 it in Django 7. The final code in Django 7 would look like:

 {{{#!diff
 diff --git a/django/contrib/auth/middleware.py
 b/django/contrib/auth/middleware.py
 index a28e1705a3..7136a64c44 100644
 --- a/django/contrib/auth/middleware.py
 +++ b/django/contrib/auth/middleware.py
 @@ -184,7 +184,7 @@ class RemoteUserMiddleware:
                  " before the RemoteUserMiddleware class."
              )
          try:
 -            username = request.META["HTTP_" + self.header]
 +            username = request.META[self.header]
          except KeyError:
              # If specified header doesn't exist then remove any existing
              # authenticated remote-user, or return (leaving request.user
 set to
 }}}

 Regrettably, we might need a transitional setting (or class attribute) to
 be able to opt into (or out of) the future, since I'm reluctant to add any
 automatic checking of other forms of headers, which will just open an
 avenue for security reports describing header spoofing. Open to ideas.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/37025>
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 visit 
https://groups.google.com/d/msgid/django-updates/0107019d695a54da-b5844039-9b5a-49f0-badf-162eab1535d9-000000%40eu-central-1.amazonses.com.

Reply via email to