+43
-7
lines changedFilter options
+43
-7
lines changed Original file line number Diff line number Diff line change
@@ -199,13 +199,14 @@ def _get_scheme(self):
199
199
def scheme(self):
200
200
if settings.SECURE_PROXY_SSL_HEADER:
201
201
try:
202
-
header, value = settings.SECURE_PROXY_SSL_HEADER
202
+
header, secure_value = settings.SECURE_PROXY_SSL_HEADER
203
203
except ValueError:
204
204
raise ImproperlyConfigured(
205
205
'The SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.'
206
206
)
207
-
if self.META.get(header) == value:
208
-
return 'https'
207
+
header_value = self.META.get(header)
208
+
if header_value is not None:
209
+
return 'https' if header_value == secure_value else 'http'
209
210
return self._get_scheme()
210
211
211
212
def is_secure(self):
Original file line number Diff line number Diff line change
@@ -2189,10 +2189,13 @@ whether a request is secure by looking at whether the requested URL uses
2189
2189
"https://". This is important for Django's CSRF protection, and may be used
2190
2190
by your own code or third-party apps.
2191
2191
2192
-
If your Django app is behind a proxy, though, the proxy may be "swallowing" the
2193
-
fact that a request is HTTPS, using a non-HTTPS connection between the proxy
2194
-
and Django. In this case, ``is_secure()`` would always return ``False`` -- even
2195
-
for requests that were made via HTTPS by the end user.
2192
+
If your Django app is behind a proxy, though, the proxy may be "swallowing"
2193
+
whether the original request uses HTTPS or not. If there is a non-HTTPS
2194
+
connection between the proxy and Django then ``is_secure()`` would always
2195
+
return ``False`` -- even for requests that were made via HTTPS by the end user.
2196
+
In contrast, if there is an HTTPS connection between the proxy and Django then
2197
+
``is_secure()`` would always return ``True`` -- even for requests that were
2198
+
made originally via HTTP.
2196
2199
2197
2200
In this situation, you'll want to configure your proxy to set a custom HTTP
2198
2201
header that tells Django whether the request came in via HTTPS, and you'll want
Original file line number Diff line number Diff line change
@@ -5,3 +5,23 @@ Django 1.11.22 release notes
5
5
*July 1, 2019*
6
6
7
7
Django 1.11.22 fixes a security issue in 1.11.21.
8
+
9
+
CVE-2019-12781: Incorrect HTTP detection with reverse-proxy connecting via HTTPS
10
+
--------------------------------------------------------------------------------
11
+
12
+
When deployed behind a reverse-proxy connecting to Django via HTTPS,
13
+
:attr:`django.http.HttpRequest.scheme` would incorrectly detect client
14
+
requests made via HTTP as using HTTPS. This entails incorrect results for
15
+
:meth:`~django.http.HttpRequest.is_secure`, and
16
+
:meth:`~django.http.HttpRequest.build_absolute_uri`, and that HTTP
17
+
requests would not be redirected to HTTPS in accordance with
18
+
:setting:`SECURE_SSL_REDIRECT`.
19
+
20
+
``HttpRequest.scheme`` now respects :setting:`SECURE_PROXY_SSL_HEADER`, if it
21
+
is configured, and the appropriate header is set on the request, for both HTTP
22
+
and HTTPS requests.
23
+
24
+
If you deploy Django behind a reverse-proxy that forwards HTTP requests, and
25
+
that connects to Django via HTTPS, be sure to verify that your application
26
+
correctly handles code paths relying on ``scheme``, ``is_secure()``,
27
+
``build_absolute_uri()``, and ``SECURE_SSL_REDIRECT``.
Original file line number Diff line number Diff line change
@@ -334,6 +334,18 @@ def test_set_with_xheader_right(self):
334
334
req.META['HTTP_X_FORWARDED_PROTOCOL'] = 'https'
335
335
self.assertIs(req.is_secure(), True)
336
336
337
+
@override_settings(SECURE_PROXY_SSL_HEADER=('HTTP_X_FORWARDED_PROTOCOL', 'https'))
338
+
def test_xheader_preferred_to_underlying_request(self):
339
+
class ProxyRequest(HttpRequest):
340
+
def _get_scheme(self):
341
+
"""Proxy always connecting via HTTPS"""
342
+
return 'https'
343
+
344
+
# Client connects via HTTP.
345
+
req = ProxyRequest()
346
+
req.META['HTTP_X_FORWARDED_PROTOCOL'] = 'http'
347
+
self.assertIs(req.is_secure(), False)
348
+
337
349
338
350
class IsOverriddenTest(SimpleTestCase):
339
351
def test_configure(self):
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4