﻿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
37025	Deprecate the prefixing of HTTP_ to header names in RemoteUserMiddleware.aprocess_request()	Jacob Walls	Jacob Walls	"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.

"	Bug	assigned	contrib.auth	5.2	Normal			Jon Janzen	Unreviewed	0	0	0	0	0	0
