diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index c7b6c2a4ea..9920c0391c 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -415,7 +415,7 @@ DEFAULT_TABLESPACE = '' DEFAULT_INDEX_TABLESPACE = '' # Default X-Frame-Options header value -X_FRAME_OPTIONS = 'SAMEORIGIN' +X_FRAME_OPTIONS = 'DENY' USE_X_FORWARDED_HOST = False USE_X_FORWARDED_PORT = False diff --git a/django/core/checks/security/base.py b/django/core/checks/security/base.py index d3daaa3cec..dce2039a36 100644 --- a/django/core/checks/security/base.py +++ b/django/core/checks/security/base.py @@ -80,9 +80,8 @@ W019 = Warning( "You have " "'django.middleware.clickjacking.XFrameOptionsMiddleware' in your " "MIDDLEWARE, but X_FRAME_OPTIONS is not set to 'DENY'. " - "The default is 'SAMEORIGIN', but unless there is a good reason for " - "your site to serve other parts of itself in a frame, you should " - "change it to 'DENY'.", + "Unless there is a good reason for your site to serve other parts of " + "itself in a frame, you should change it to 'DENY'.", id='security.W019', ) diff --git a/django/middleware/clickjacking.py b/django/middleware/clickjacking.py index a0506142b9..478ed3cd7e 100644 --- a/django/middleware/clickjacking.py +++ b/django/middleware/clickjacking.py @@ -37,9 +37,9 @@ class XFrameOptionsMiddleware(MiddlewareMixin): def get_xframe_options_value(self, request, response): """ Get the value to set for the X_FRAME_OPTIONS header. Use the value from - the X_FRAME_OPTIONS setting, or 'SAMEORIGIN' if not set. + the X_FRAME_OPTIONS setting, or 'DENY' if not set. This method can be overridden if needed, allowing it to vary based on the request or response. """ - return getattr(settings, 'X_FRAME_OPTIONS', 'SAMEORIGIN').upper() + return getattr(settings, 'X_FRAME_OPTIONS', 'DENY').upper() diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 88b09b008d..4da932720e 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -420,9 +420,8 @@ The following checks are run if you use the :option:`check --deploy` option: * **security.W019**: You have :class:`django.middleware.clickjacking.XFrameOptionsMiddleware` in your :setting:`MIDDLEWARE`, but :setting:`X_FRAME_OPTIONS` is not set to - ``'DENY'``. The default is ``'SAMEORIGIN'``, but unless there is a good reason - for your site to serve other parts of itself in a frame, you should change - it to ``'DENY'``. + ``'DENY'``. Unless there is a good reason for your site to serve other parts + of itself in a frame, you should change it to ``'DENY'``. * **security.W020**: :setting:`ALLOWED_HOSTS` must not be empty in deployment. * **security.W021**: You have not set the :setting:`SECURE_HSTS_PRELOAD` setting to ``True``. Without this, your site diff --git a/docs/ref/clickjacking.txt b/docs/ref/clickjacking.txt index 88b45fd63b..c7cac17ca4 100644 --- a/docs/ref/clickjacking.txt +++ b/docs/ref/clickjacking.txt @@ -67,10 +67,15 @@ This middleware is enabled in the settings file generated by :djadmin:`startproject`. By default, the middleware will set the ``X-Frame-Options`` header to -``SAMEORIGIN`` for every outgoing ``HttpResponse``. If you want ``DENY`` -instead, set the :setting:`X_FRAME_OPTIONS` setting:: +``DENY`` for every outgoing ``HttpResponse``. If you want any other value for +this header instead, set the :setting:`X_FRAME_OPTIONS` setting:: - X_FRAME_OPTIONS = 'DENY' + X_FRAME_OPTIONS = 'SAMEORIGIN' + +.. versionchanged:: 3.0 + + The default value of the :setting:`X_FRAME_OPTIONS` setting was changed + from ``SAMEORIGIN`` to ``DENY``. When using the middleware there may be some views where you do **not** want the ``X-Frame-Options`` header set. For those cases, you can use a view decorator @@ -116,6 +121,7 @@ Browsers that support ``X-Frame-Options`` ----------------------------------------- * Internet Explorer 8+ +* Edge * Firefox 3.6.9+ * Opera 10.5+ * Safari 4+ diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 493d99e92a..aa9bc1ddb8 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -2795,12 +2795,15 @@ and :setting:`MONTH_DAY_FORMAT`. ``X_FRAME_OPTIONS`` ------------------- -Default: ``'SAMEORIGIN'`` +Default: ``'DENY'`` The default value for the X-Frame-Options header used by :class:`~django.middleware.clickjacking.XFrameOptionsMiddleware`. See the :doc:`clickjacking protection ` documentation. +.. versionchanged:: 3.0 + + In older versions, the default value is ``SAMEORIGIN``. Auth ==== diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt index a105abfae6..1fc64a442d 100644 --- a/docs/releases/3.0.txt +++ b/docs/releases/3.0.txt @@ -535,6 +535,15 @@ upload handler is used. ``FILE_UPLOAD_PERMISSION`` now defaults to ``0o644`` to avoid this inconsistency. +New default value for the ``X_FRAME_OPTIONS`` setting +----------------------------------------------------- + +In older versions, the :setting:`X_FRAME_OPTIONS` setting defaults to +``'SAMEORIGIN'``. To make Django projects more secure by default, +:setting:`X_FRAME_OPTIONS` now defaults to ``'DENY'``. If your site uses frames +of itself, you will need to explicitly set ``X_FRAME_ORIGINS = 'SAMEORIGIN'`` +for them to continue working. + Miscellaneous ------------- diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 971fe0a74a..def313c5f7 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -621,12 +621,12 @@ class XFrameOptionsMiddlewareTest(SimpleTestCase): def test_defaults_sameorigin(self): """ If the X_FRAME_OPTIONS setting is not set then it defaults to - SAMEORIGIN. + DENY. """ with override_settings(X_FRAME_OPTIONS=None): del settings.X_FRAME_OPTIONS # restored by override_settings r = XFrameOptionsMiddleware().process_response(HttpRequest(), HttpResponse()) - self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN') + self.assertEqual(r['X-Frame-Options'], 'DENY') def test_dont_set_if_set(self): """ diff --git a/tests/project_template/test_settings.py b/tests/project_template/test_settings.py index c76564c656..5617f4a943 100644 --- a/tests/project_template/test_settings.py +++ b/tests/project_template/test_settings.py @@ -39,5 +39,5 @@ class TestStartProjectSettings(SimpleTestCase): b'Content-Length: 0', b'Content-Type: text/html; charset=utf-8', b'X-Content-Type-Options: nosniff', - b'X-Frame-Options: SAMEORIGIN', + b'X-Frame-Options: DENY', ])