#33569: Add support for multiple values for the x-forwarded-proto header
-------------------------------------+-------------------------------------
Reporter: Thomas Schmidt | Owner: Thomas
Type: | Schmidt
Cleanup/optimization | Status: closed
Component: HTTP handling | Version: dev
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Florian Apolloner):
> As far as I'm aware, we cannot answer in the reliable way whether the
request was over HTTPS, when `X-Forwarded-Proto` contains multiple values.
Unfortunately it depends on which layer is trusted. We could check if all
values are "https", but this could be unacceptable with in-companies
proxies. It's definitely not enough to check if "https" is used somewhere
in the pipeline.
I do not think this is correct. First of all we have to make one decision
-- namely do we want to trust `X-Forwarded-Proto` at all. By setting
`SECURE_PROXY_SSL_HEADER` we do explicitly say that we trust the value to
be correct (see the big warning in
https://docs.djangoproject.com/en/4.0/ref/settings/).
Once we trust that header it is not required to check whether all items in
the list are `https` but solely whether the left one is `https`. Whether
the middle-items are `http` is irrelevant. Why? The goal of this header is
to check if the client connection to the first proxy was HTTPS, nothing
more nothing less. It is not an indicator on whether the connection is
secure but solely an indicator whether generated links etc should have
https:// or http://.
For example even if the header is set to the simple value of `https` there
is no gurantee that the connection from the proxy to the backend was https
(and more often than not it is simply http).
> As a workaround you can set list of protocols in the
`SECURE_PROXY_SSL_HEADER`, e.g. `SECURE_PROXY_SSL_HEADER =
("HTTP_X_FORWARDED_PROTO", "https,http")`.
I am not sure I would recommend that, this is highly implementation
dependent and assumes that the proxy doesn't start sneaking in a space at
some point. That said the worst case scenario here is then that the
request is determined as unsafe which is probably not the end of the
world… On the other hand this assumes that you actually know the number of
proxies involved as opposed to just knowing that you can trust the header
because the proxies to set it properly. Which might be hard in cloud
environments.
> I don't think it's worth additional complexity.
I would argue that the added complexity is relatively small; the biggest
task here is to update the docs to explain it nicely.
--
Ticket URL: <https://code.djangoproject.com/ticket/33569#comment:5>
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/0107017f72e4c4cd-bc2689a8-4c53-4e38-8173-df85efc51a6c-000000%40eu-central-1.amazonses.com.