From d308d329ce43770b7eac93d131552f35e51182ff Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Wed, 25 Sep 2019 18:06:22 +0100 Subject: [PATCH] 22: Enable SSL redirect and other security settings (#203) * 22: Enable recommended-by-Django security settings as defaults The base settings now follow all-but-one of the recommendations from manage.py `check --deploy`. The only one that's not been done in this changeset is SECURE_HSTS_SECONDS, because of the risk of "serious, irreversible problems". That needs to be planned in to enable it properly. Note that we're explicitly setting what HTTP header to look for to detect the SSL-forwarded header, which should stop the redirect loop in production. Development settings turn off SSL redirect, because the local build isn't set to use HTTPS. (It could be tweaked to use HTTPS, too - but that's out of scope for this piece) * 22: Address issue with wagtail-bakery where SECURE_SSL_REDIRECT=True bakes out empty HTML This commit subclasses wagtail-bakery's `AllPublishedPagesView` in a way that detects application-level SSL redirection in order to avoid an issue where rendered pages end up being 0 bytes. See https://github.com/wagtail/wagtail-bakery/issues/24 for confirmation of the issue and the discussion on https://github.com/wagtail/wagtail-bakery/pull/25 that points to a custom view being the (current) workaround. Ideally we'll be able to replace this when that issue is resolved. The code in this commit is basically taken from that closed PR, which adds the `secure_request` variable. Hat-tip to @loicteixeira - thanks! No unit test added, but manually tested locally to confirm this does indeed fix the static build while `SECURE_SSL_REDIRECT` is `True` --- developerportal/apps/bakery/views.py | 39 ++++++++++++++++++++++++++++ developerportal/settings/base.py | 14 +++++++++- developerportal/settings/dev.py | 1 + 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 developerportal/apps/bakery/views.py diff --git a/developerportal/apps/bakery/views.py b/developerportal/apps/bakery/views.py new file mode 100644 index 000000000..73bebe856 --- /dev/null +++ b/developerportal/apps/bakery/views.py @@ -0,0 +1,39 @@ +import logging + +from django.conf import settings +from django.test.client import RequestFactory + +from wagtailbakery.views import AllPublishedPagesView + +logger = logging.getLogger(__name__) + + +class AllPublishedPagesViewAllowingSecureRedirect(AllPublishedPagesView): + """Extension of `AllPublishedPagesView` that detects application-level SSL + redirection in order to avoid an issue where rendered pages end up being 0 bytes + + See https://github.com/wagtail/wagtail-bakery/issues/24 for confirmation of the + issue and the discussion on https://github.com/wagtail/wagtail-bakery/pull/25 + that points to a custom view being the (current) workaround. Ideally we'll be + able to replace this when that issue is resolved. + + The following code is taken from that closed PR, which adds the `secure_request` + variable. + """ + + def build_object(self, obj): + """ + Build wagtail page and set SERVER_NAME to retrieve corresponding site + object. + """ + site = obj.get_site() + logger.debug("Building %s" % obj) + secure_request = site.port == 443 or getattr( + settings, "SECURE_SSL_REDIRECT", False + ) + self.request = RequestFactory(SERVER_NAME=site.hostname).get( + self.get_url(obj), secure=secure_request + ) + self.set_kwargs(obj) + path = self.get_build_path(obj) + self.build_file(path, self.get_content(obj)) diff --git a/developerportal/settings/base.py b/developerportal/settings/base.py index 4fe1663f4..2f1fb9e60 100644 --- a/developerportal/settings/base.py +++ b/developerportal/settings/base.py @@ -188,6 +188,16 @@ MEDIA_URL = "/media/" +# Django security settings (see `manage.py check --deploy`) + +CSRF_COOKIE_SECURE = True +SECURE_BROWSER_XSS_FILTER = True +SECURE_CONTENT_TYPE_NOSNIFF = True +SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") +SECURE_SSL_REDIRECT = True +SESSION_COOKIE_SECURE = True +X_FRAME_OPTIONS = "DENY" + # Wagtail settings WAGTAIL_SITE_NAME = "Mozilla Developers" @@ -215,7 +225,9 @@ # Wagtail Bakery Settings BUILD_DIR = os.path.join(BASE_DIR, "build") BAKERY_MULTISITE = True -BAKERY_VIEWS = ("wagtailbakery.views.AllPublishedPagesView",) +BAKERY_VIEWS = ( + "developerportal.apps.bakery.views.AllPublishedPagesViewAllowingSecureRedirect", +) AWS_REGION = os.environ.get("AWS_REGION") AWS_BUCKET_NAME = os.environ.get("AWS_BUCKET_NAME") diff --git a/developerportal/settings/dev.py b/developerportal/settings/dev.py index b44f7debd..57c44178a 100644 --- a/developerportal/settings/dev.py +++ b/developerportal/settings/dev.py @@ -8,6 +8,7 @@ EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" +SECURE_SSL_REDIRECT = False try: from .local import *