summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorLuke Plant <L.Plant.98@cantab.net>2011-05-30 22:27:47 +0000
committerLuke Plant <L.Plant.98@cantab.net>2011-05-30 22:27:47 +0000
commit524c5fa07a38cc68a81a12428befdafcfde1afc3 (patch)
tree88a59e2870cf181d1165414feb55b6d96e8ff414 /tests
parentdc4c2f3add4f15edf05574e6e8eb101be9da4b90 (diff)
Fixed #14261 - Added clickjacking protection (X-Frame-Options header)
Many thanks to rniemeyer for the patch! git-svn-id: http://code.djangoproject.com/svn/django/trunk@16298 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
-rw-r--r--tests/regressiontests/decorators/tests.py46
-rw-r--r--tests/regressiontests/middleware/tests.py124
2 files changed, 170 insertions, 0 deletions
diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py
index d9a6b4caf7..8a03980f88 100644
--- a/tests/regressiontests/decorators/tests.py
+++ b/tests/regressiontests/decorators/tests.py
@@ -9,6 +9,8 @@ from django.utils.unittest import TestCase
from django.views.decorators.http import require_http_methods, require_GET, require_POST, require_safe
from django.views.decorators.vary import vary_on_headers, vary_on_cookie
from django.views.decorators.cache import cache_page, never_cache, cache_control
+from django.views.decorators.clickjacking import xframe_options_deny, xframe_options_sameorigin, xframe_options_exempt
+from django.middleware.clickjacking import XFrameOptionsMiddleware
def fully_decorated(request):
@@ -216,3 +218,47 @@ class MethodDecoratorTests(TestCase):
self.assertEqual(Test.method.__doc__, 'A method')
self.assertEqual(Test.method.im_func.__name__, 'method')
+
+
+class XFrameOptionsDecoratorsTests(TestCase):
+ """
+ Tests for the X-Frame-Options decorators.
+ """
+ def test_deny_decorator(self):
+ """
+ Ensures @xframe_options_deny properly sets the X-Frame-Options header.
+ """
+ @xframe_options_deny
+ def a_view(request):
+ return HttpResponse()
+ r = a_view(HttpRequest())
+ self.assertEqual(r['X-Frame-Options'], 'DENY')
+
+ def test_sameorigin_decorator(self):
+ """
+ Ensures @xframe_options_sameorigin properly sets the X-Frame-Options
+ header.
+ """
+ @xframe_options_sameorigin
+ def a_view(request):
+ return HttpResponse()
+ r = a_view(HttpRequest())
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ def test_exempt_decorator(self):
+ """
+ Ensures @xframe_options_exempt properly instructs the
+ XFrameOptionsMiddleware to NOT set the header.
+ """
+ @xframe_options_exempt
+ def a_view(request):
+ return HttpResponse()
+ req = HttpRequest()
+ resp = a_view(req)
+ self.assertEqual(resp.get('X-Frame-Options', None), None)
+ self.assertTrue(resp.xframe_options_exempt)
+
+ # Since the real purpose of the exempt decorator is to suppress
+ # the middleware's functionality, let's make sure it actually works...
+ r = XFrameOptionsMiddleware().process_response(req, resp)
+ self.assertEqual(r.get('X-Frame-Options', None), None)
diff --git a/tests/regressiontests/middleware/tests.py b/tests/regressiontests/middleware/tests.py
index c069228487..124eb191f0 100644
--- a/tests/regressiontests/middleware/tests.py
+++ b/tests/regressiontests/middleware/tests.py
@@ -5,6 +5,8 @@ import re
from django.conf import settings
from django.core import mail
from django.http import HttpRequest
+from django.http import HttpResponse
+from django.middleware.clickjacking import XFrameOptionsMiddleware
from django.middleware.common import CommonMiddleware
from django.middleware.http import ConditionalGetMiddleware
from django.test import TestCase
@@ -371,3 +373,125 @@ class ConditionalGetMiddlewareTest(TestCase):
self.resp['Last-Modified'] = 'Sat, 12 Feb 2011 17:41:44 GMT'
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
self.assertEqual(self.resp.status_code, 200)
+
+
+class XFrameOptionsMiddlewareTest(TestCase):
+ """
+ Tests for the X-Frame-Options clickjacking prevention middleware.
+ """
+ def setUp(self):
+ self.x_frame_options = settings.X_FRAME_OPTIONS
+
+ def tearDown(self):
+ settings.X_FRAME_OPTIONS = self.x_frame_options
+
+ def test_same_origin(self):
+ """
+ Tests that the X_FRAME_OPTIONS setting can be set to SAMEORIGIN to
+ have the middleware use that value for the HTTP header.
+ """
+ settings.X_FRAME_OPTIONS = 'SAMEORIGIN'
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ HttpResponse())
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ settings.X_FRAME_OPTIONS = 'sameorigin'
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ HttpResponse())
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ def test_deny(self):
+ """
+ Tests that the X_FRAME_OPTIONS setting can be set to DENY to
+ have the middleware use that value for the HTTP header.
+ """
+ settings.X_FRAME_OPTIONS = 'DENY'
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ HttpResponse())
+ self.assertEqual(r['X-Frame-Options'], 'DENY')
+
+ settings.X_FRAME_OPTIONS = 'deny'
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ HttpResponse())
+ self.assertEqual(r['X-Frame-Options'], 'DENY')
+
+ def test_defaults_sameorigin(self):
+ """
+ Tests that if the X_FRAME_OPTIONS setting is not set then it defaults
+ to SAMEORIGIN.
+ """
+ del settings.X_FRAME_OPTIONS
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ HttpResponse())
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ def test_dont_set_if_set(self):
+ """
+ Tests that if the X-Frame-Options header is already set then the
+ middleware does not attempt to override it.
+ """
+ settings.X_FRAME_OPTIONS = 'DENY'
+ response = HttpResponse()
+ response['X-Frame-Options'] = 'SAMEORIGIN'
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ response)
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ settings.X_FRAME_OPTIONS = 'SAMEORIGIN'
+ response = HttpResponse()
+ response['X-Frame-Options'] = 'DENY'
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ response)
+ self.assertEqual(r['X-Frame-Options'], 'DENY')
+
+ def test_response_exempt(self):
+ """
+ Tests that if the response has a xframe_options_exempt attribute set
+ to False then it still sets the header, but if it's set to True then
+ it does not.
+ """
+ settings.X_FRAME_OPTIONS = 'SAMEORIGIN'
+ response = HttpResponse()
+ response.xframe_options_exempt = False
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ response)
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ response = HttpResponse()
+ response.xframe_options_exempt = True
+ r = XFrameOptionsMiddleware().process_response(HttpRequest(),
+ response)
+ self.assertEqual(r.get('X-Frame-Options', None), None)
+
+ def test_is_extendable(self):
+ """
+ Tests that the XFrameOptionsMiddleware method that determines the
+ X-Frame-Options header value can be overridden based on something in
+ the request or response.
+ """
+ class OtherXFrameOptionsMiddleware(XFrameOptionsMiddleware):
+ # This is just an example for testing purposes...
+ def get_xframe_options_value(self, request, response):
+ if getattr(request, 'sameorigin', False):
+ return 'SAMEORIGIN'
+ if getattr(response, 'sameorigin', False):
+ return 'SAMEORIGIN'
+ return 'DENY'
+
+ settings.X_FRAME_OPTIONS = 'DENY'
+ response = HttpResponse()
+ response.sameorigin = True
+ r = OtherXFrameOptionsMiddleware().process_response(HttpRequest(),
+ response)
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ request = HttpRequest()
+ request.sameorigin = True
+ r = OtherXFrameOptionsMiddleware().process_response(request,
+ HttpResponse())
+ self.assertEqual(r['X-Frame-Options'], 'SAMEORIGIN')
+
+ settings.X_FRAME_OPTIONS = 'SAMEORIGIN'
+ r = OtherXFrameOptionsMiddleware().process_response(HttpRequest(),
+ HttpResponse())
+ self.assertEqual(r['X-Frame-Options'], 'DENY')