diff options
| author | Luke Plant <L.Plant.98@cantab.net> | 2011-05-30 22:27:47 +0000 |
|---|---|---|
| committer | Luke Plant <L.Plant.98@cantab.net> | 2011-05-30 22:27:47 +0000 |
| commit | 524c5fa07a38cc68a81a12428befdafcfde1afc3 (patch) | |
| tree | 88a59e2870cf181d1165414feb55b6d96e8ff414 /tests | |
| parent | dc4c2f3add4f15edf05574e6e8eb101be9da4b90 (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.py | 46 | ||||
| -rw-r--r-- | tests/regressiontests/middleware/tests.py | 124 |
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') |
