mirror of
https://github.com/django/django.git
synced 2024-12-23 01:25:58 +00:00
Refs #15727 -- Add support for Content-Security-Policy (CSP) to SecurityMiddleware
This commit is contained in:
parent
0ec60661e6
commit
87bb837e18
@ -665,3 +665,8 @@ SECURE_REDIRECT_EXEMPT = []
|
|||||||
SECURE_REFERRER_POLICY = "same-origin"
|
SECURE_REFERRER_POLICY = "same-origin"
|
||||||
SECURE_SSL_HOST = None
|
SECURE_SSL_HOST = None
|
||||||
SECURE_SSL_REDIRECT = False
|
SECURE_SSL_REDIRECT = False
|
||||||
|
SECURE_CSP = {}
|
||||||
|
SECURE_CSP_REPORT_ONLY = False
|
||||||
|
SECURE_CSP_MULTIPLE = None
|
||||||
|
SECURE_CSP_INCLUDE_NONCE_IN = None
|
||||||
|
SECURE_CSP_EXCLUDE_URL_PREFIXES = ()
|
||||||
|
@ -17,6 +17,11 @@ class SecurityMiddleware(MiddlewareMixin):
|
|||||||
self.redirect_exempt = [re.compile(r) for r in settings.SECURE_REDIRECT_EXEMPT]
|
self.redirect_exempt = [re.compile(r) for r in settings.SECURE_REDIRECT_EXEMPT]
|
||||||
self.referrer_policy = settings.SECURE_REFERRER_POLICY
|
self.referrer_policy = settings.SECURE_REFERRER_POLICY
|
||||||
self.cross_origin_opener_policy = settings.SECURE_CROSS_ORIGIN_OPENER_POLICY
|
self.cross_origin_opener_policy = settings.SECURE_CROSS_ORIGIN_OPENER_POLICY
|
||||||
|
self.csp = settings.SECURE_CSP
|
||||||
|
self.csp_multiple = settings.SECURE_CSP_MULTIPLE
|
||||||
|
self.csp_report_only = settings.SECURE_CSP_REPORT_ONLY
|
||||||
|
self.csp_nonce = settings.SECURE_CSP_INCLUDE_NONCE_IN
|
||||||
|
self.csp_exclude_url_prefixes = settings.SECURE_CSP_EXCLUDE_URL_PREFIXES
|
||||||
|
|
||||||
def process_request(self, request):
|
def process_request(self, request):
|
||||||
path = request.path.lstrip("/")
|
path = request.path.lstrip("/")
|
||||||
@ -63,4 +68,33 @@ class SecurityMiddleware(MiddlewareMixin):
|
|||||||
"Cross-Origin-Opener-Policy",
|
"Cross-Origin-Opener-Policy",
|
||||||
self.cross_origin_opener_policy,
|
self.cross_origin_opener_policy,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if request.path_info.startswith(self.csp_exclude_url_prefixes):
|
||||||
|
return response
|
||||||
|
|
||||||
|
if self.csp:
|
||||||
|
header = "Content-Security-Policy"
|
||||||
|
csp_header_value = "; ".join((f"{k} {v}" for k, v in self.csp.items()))
|
||||||
|
|
||||||
|
if self.csp_report_only:
|
||||||
|
header += "-Report-Only"
|
||||||
|
|
||||||
|
if self.csp_nonce:
|
||||||
|
nonce = getattr(request, "_csp_nonce", None)
|
||||||
|
csp_header_value += "; 'nonce-%s'" % nonce
|
||||||
|
response.headers[header] = csp_header_value
|
||||||
|
|
||||||
|
if self.csp_multiple:
|
||||||
|
# Support a comma-separated string or iterable of values to allow
|
||||||
|
# fallback.
|
||||||
|
header = "Content-Security-Policy"
|
||||||
|
csp_header_value = "; ".join(
|
||||||
|
[v.strip() for v in self.csp_multiple.split(";")]
|
||||||
|
if isinstance(self.csp_multiple, str)
|
||||||
|
else self.csp_multiple
|
||||||
|
)
|
||||||
|
if self.csp_report_only:
|
||||||
|
header += "-Report-Only"
|
||||||
|
response.headers[header] = csp_header_value
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
@ -87,3 +87,9 @@ def media(request):
|
|||||||
|
|
||||||
def request(request):
|
def request(request):
|
||||||
return {"request": request}
|
return {"request": request}
|
||||||
|
|
||||||
|
|
||||||
|
def nonce(request):
|
||||||
|
nonce = request.csp_nonce if hasattr(request, "csp_nonce") else ""
|
||||||
|
|
||||||
|
return {"CSP_NONCE": nonce}
|
||||||
|
16
django/views/decorators/csp.py
Normal file
16
django/views/decorators/csp.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def csp(**kwargs):
|
||||||
|
csp_header_value = "; ".join((f"{k} {v}" for k, v in kwargs.items()))
|
||||||
|
|
||||||
|
def decorator(f):
|
||||||
|
@wraps(f)
|
||||||
|
def _wrapped(*a, **kw):
|
||||||
|
resp = f(*a, **kw) # response object from the view
|
||||||
|
resp["Content-Security-Policy"] = csp_header_value
|
||||||
|
return resp
|
||||||
|
|
||||||
|
return _wrapped
|
||||||
|
|
||||||
|
return decorator
|
Loading…
Reference in New Issue
Block a user