1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
from django.http import (
HttpResponse,
HttpResponseNotFound,
HttpResponseServerError,
)
from django.test import RequestFactory
from django.test.utils import override_settings
from csp.middleware import CSPMiddleware
from csp.tests.utils import response
HEADER = "Content-Security-Policy"
mw = CSPMiddleware(response())
rf = RequestFactory()
def test_add_header():
request = rf.get("/")
response = HttpResponse()
mw.process_response(request, response)
assert HEADER in response
def test_exempt():
request = rf.get("/")
response = HttpResponse()
response._csp_exempt = True
mw.process_response(request, response)
assert HEADER not in response
@override_settings(CSP_EXCLUDE_URL_PREFIXES=("/inlines-r-us"))
def text_exclude():
request = rf.get("/inlines-r-us/foo")
response = HttpResponse()
mw.process_response(request, response)
assert HEADER not in response
@override_settings(CSP_REPORT_ONLY=True)
def test_report_only():
request = rf.get("/")
response = HttpResponse()
mw.process_response(request, response)
assert HEADER not in response
assert HEADER + "-Report-Only" in response
def test_dont_replace():
request = rf.get("/")
response = HttpResponse()
response[HEADER] = "default-src example.com"
mw.process_response(request, response)
assert response[HEADER] == "default-src example.com"
def test_use_config():
request = rf.get("/")
response = HttpResponse()
response._csp_config = {"default-src": ["example.com"]}
mw.process_response(request, response)
assert response[HEADER] == "default-src example.com"
def test_use_update():
request = rf.get("/")
response = HttpResponse()
response._csp_update = {"default-src": ["example.com"]}
mw.process_response(request, response)
assert response[HEADER] == "default-src 'self' example.com"
@override_settings(CSP_IMG_SRC=["foo.com"])
def test_use_replace():
request = rf.get("/")
response = HttpResponse()
response._csp_replace = {"img-src": ["bar.com"]}
mw.process_response(request, response)
policy_list = sorted(response[HEADER].split("; "))
assert policy_list == ["default-src 'self'", "img-src bar.com"]
@override_settings(DEBUG=True)
def test_debug_errors_exempt():
request = rf.get("/")
response = HttpResponseServerError()
mw.process_response(request, response)
assert HEADER not in response
@override_settings(DEBUG=True)
def test_debug_notfound_exempt():
request = rf.get("/")
response = HttpResponseNotFound()
mw.process_response(request, response)
assert HEADER not in response
def test_nonce_created_when_accessed():
request = rf.get("/")
mw.process_request(request)
nonce = str(request.csp_nonce)
response = HttpResponse()
mw.process_response(request, response)
assert nonce in response[HEADER]
def test_no_nonce_when_not_accessed():
request = rf.get("/")
mw.process_request(request)
response = HttpResponse()
mw.process_response(request, response)
assert "nonce-" not in response[HEADER]
def test_nonce_regenerated_on_new_request():
request1 = rf.get("/")
request2 = rf.get("/")
mw.process_request(request1)
mw.process_request(request2)
nonce1 = str(request1.csp_nonce)
nonce2 = str(request2.csp_nonce)
assert request1.csp_nonce != request2.csp_nonce
response1 = HttpResponse()
response2 = HttpResponse()
mw.process_response(request1, response1)
mw.process_response(request2, response2)
assert nonce1 not in response2[HEADER]
assert nonce2 not in response1[HEADER]
@override_settings(CSP_INCLUDE_NONCE_IN=[])
def test_no_nonce_when_disabled_by_settings():
request = rf.get("/")
mw.process_request(request)
nonce = str(request.csp_nonce)
response = HttpResponse()
mw.process_response(request, response)
assert nonce not in response[HEADER]
|