Skip to content

Commit b83448b

Browse files
authored
Clarify the secure scheme behaviour, with examples (#2492)
1 parent 2ffc1b7 commit b83448b

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

gunicorn/config.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,10 +1236,16 @@ class SecureSchemeHeader(Setting):
12361236
desc = """\
12371237
12381238
A dictionary containing headers and values that the front-end proxy
1239-
uses to indicate HTTPS requests. These tell Gunicorn to set
1239+
uses to indicate HTTPS requests. If the source IP is permitted by
1240+
``forwarded-allow-ips`` (below), *and* at least one request header matches
1241+
a key-value pair listed in this dictionary, then Gunicorn will set
12401242
``wsgi.url_scheme`` to ``https``, so your application can tell that the
12411243
request is secure.
12421244
1245+
If the other headers listed in this dictionary are not present in the request, they will be ignored,
1246+
but if the other headers are present and do not match the provided values, then
1247+
the request will fail to parse. See the note below for more detailed examples of this behaviour.
1248+
12431249
The dictionary should map upper-case header names to exact string
12441250
values. The value comparisons are case-sensitive, unlike the header
12451251
names, so make sure they're exactly what your front-end proxy sends
@@ -1267,6 +1273,70 @@ class ForwardedAllowIPS(Setting):
12671273
12681274
By default, the value of the ``FORWARDED_ALLOW_IPS`` environment
12691275
variable. If it is not defined, the default is ``"127.0.0.1"``.
1276+
1277+
.. note::
1278+
1279+
The interplay between the request headers, the value of ``forwarded_allow_ips``, and the value of
1280+
``secure_scheme_headers`` is complex. Various scenarios are documented below to further elaborate. In each case, we
1281+
have a request from the remote address 134.213.44.18, and the default value of ``secure_scheme_headers``:
1282+
1283+
.. code::
1284+
1285+
secure_scheme_headers = {
1286+
'X-FORWARDED-PROTOCOL': 'ssl',
1287+
'X-FORWARDED-PROTO': 'https',
1288+
'X-FORWARDED-SSL': 'on'
1289+
}
1290+
1291+
1292+
.. list-table::
1293+
:header-rows: 1
1294+
:align: center
1295+
:widths: auto
1296+
1297+
* - ``forwarded-allow-ips``
1298+
- Secure Request Headers
1299+
- Result
1300+
- Explanation
1301+
* - .. code::
1302+
1303+
["127.0.0.1"]
1304+
- .. code::
1305+
1306+
X-Forwarded-Proto: https
1307+
- .. code::
1308+
1309+
wsgi.url_scheme = "http"
1310+
- IP address was not allowed
1311+
* - .. code::
1312+
1313+
"*"
1314+
- <none>
1315+
- .. code::
1316+
1317+
wsgi.url_scheme = "http"
1318+
- IP address allowed, but no secure headers provided
1319+
* - .. code::
1320+
1321+
"*"
1322+
- .. code::
1323+
1324+
X-Forwarded-Proto: https
1325+
- .. code::
1326+
1327+
wsgi.url_scheme = "https"
1328+
- IP address allowed, one request header matched
1329+
* - .. code::
1330+
1331+
["134.213.44.18"]
1332+
- .. code::
1333+
1334+
X-Forwarded-Ssl: on
1335+
X-Forwarded-Proto: http
1336+
- ``InvalidSchemeHeaders()`` raised
1337+
- IP address allowed, but the two secure headers disagreed on if HTTPS was used
1338+
1339+
12701340
"""
12711341

12721342

0 commit comments

Comments
 (0)