#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.

Reply via email to