Skip to content

Commit a75e1c5

Browse files
authored
Enable redirection of HTTP requests to HTTPS (#253)
Using Django's `SECURE_SSL_REDIRECT`: https://docs.djangoproject.com/en/5.1/ref/settings/#std-setting-SECURE_SSL_REDIRECT Also configures gunicorn's `forwarded_allow_ips` setting to `"*"` so that gunicorn trusts the `X-Forwarded-Proto` header set by the Heroku Router during TLS termination, to ensure that HTTPS requests are correctly marked as secure in the WSGI metadata passed to the WSGI app (in this case, Django). See: https://docs.gunicorn.org/en/stable/settings.html#forwarded-allow-ips https://devcenter.heroku.com/articles/http-routing#heroku-headers (Whilst the classic Python buildpack already configures this by setting the env var `FORWARDED_ALLOW_IPS`, the Python CNB doesn't yet do so, and it's clearer to have the config explicitly set in the app source.) GUS-W-17482732.
1 parent a288ab1 commit a75e1c5

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

gettingstarted/settings.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,26 @@
4949
# The `DYNO` env var is set on Heroku CI, but it's not a real Heroku app, so we have to
5050
# also explicitly exclude CI:
5151
# https://devcenter.heroku.com/articles/heroku-ci#immutable-environment-variables
52-
IS_HEROKU_APP = "DYNO" in os.environ and not "CI" in os.environ
52+
IS_HEROKU_APP = "DYNO" in os.environ and "CI" not in os.environ
5353

54-
# On Heroku, it's safe to use a wildcard for `ALLOWED_HOSTS`, since the Heroku router performs
55-
# validation of the Host header in the incoming HTTP request. On other platforms you may need to
56-
# list the expected hostnames explicitly in production to prevent HTTP Host header attacks. See:
57-
# https://docs.djangoproject.com/en/5.1/ref/settings/#std-setting-ALLOWED_HOSTS
5854
if IS_HEROKU_APP:
55+
# On Heroku, it's safe to use a wildcard for `ALLOWED_HOSTS`, since the Heroku router performs
56+
# validation of the Host header in the incoming HTTP request. On other platforms you may need to
57+
# list the expected hostnames explicitly in production to prevent HTTP Host header attacks. See:
58+
# https://docs.djangoproject.com/en/5.1/ref/settings/#std-setting-ALLOWED_HOSTS
5959
ALLOWED_HOSTS = ["*"]
60+
61+
# Redirect all non-HTTPS requests to HTTPS. This requires that:
62+
# 1. Your app has a TLS/SSL certificate, which all `*.herokuapp.com` domains do by default.
63+
# When using a custom domain, you must configure one. See:
64+
# https://devcenter.heroku.com/articles/automated-certificate-management
65+
# 2. Your app's WSGI web server is configured to use the `X-Forwarded-Proto` headers set by
66+
# the Heroku Router (otherwise you may encounter infinite HTTP 301 redirects). See this
67+
# app's `gunicorn.conf.py` for how this is done when using gunicorn.
68+
#
69+
# For maximum security, consider enabling HTTP Strict Transport Security (HSTS) headers too:
70+
# https://docs.djangoproject.com/en/5.1/ref/middleware/#http-strict-transport-security
71+
SECURE_SSL_REDIRECT = True
6072
else:
6173
ALLOWED_HOSTS = [".localhost", "127.0.0.1", "[::1]", "0.0.0.0", "[::]"]
6274

gunicorn.conf.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Gunicorn configuration file:
22
# https://docs.gunicorn.org/en/stable/configure.html
33
# https://docs.gunicorn.org/en/stable/settings.html
4+
#
45
# Note: The classic Python buildpack currently sets a few gunicorn settings automatically via
56
# the `GUNICORN_CMD_ARGS` env var (which take priority over the settings in this file):
67
# https://github.com/heroku/heroku-buildpack-python/blob/main/vendor/python.gunicorn.sh
@@ -70,3 +71,9 @@
7071
# duplicate gunicorn processes have accidentally been launched (eg in different
7172
# terminals), since the "address already in use" error no longer occurs.
7273
reuse_port = True
74+
75+
# Trust the `X-Forwarded-Proto` header set by the Heroku Router during TLS termination,
76+
# (https://devcenter.heroku.com/articles/http-routing#heroku-headers) so that HTTPS requests
77+
# are correctly marked as secure. This allows the WSGI app (in our case, Django) to distinguish
78+
# between HTTP and HTTPS requests for features like HTTP->HTTPS URL redirection.
79+
forwarded_allow_ips = "*"

0 commit comments

Comments
 (0)