Swipe left or right to navigate to next or previous post
A Content Security Policy (CSP) is an effective security measure that helps protect Django applications from Cross-Site Scripting (XSS) attacks and other code injection threats. By defining CSP rules, you control how and where your application’s resources are loaded or executed.
Django applications often involve user-generated content or depend on external scripts and libraries, making them potential targets for XSS attacks. With CSP, you can:
eval()
.Django does not include native CSP support, but you can implement CSP policies using middleware or third-party packages.
Django-CSP is a popular package that integrates CSP into your Django project. Follow these steps:
pip install django-csp
django_csp.middleware.CSPMiddleware
in your MIDDLEWARE
setting.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'csp.middleware.CSPMiddleware',
# other middleware
]
settings.py
.
# These are just the examples
CSP_DEFAULT_SRC="'self'"
CSP_SCRIPT_SRC="'self','strict-dynamic','unsafe-inline',unpkg.com,npmcdn.com,ajax.googleapis.com,cdnjs.cloudflare.com"
CSP_SCRIPT_SRC_ELEM="'self',unpkg.com,npmcdn.com,ajax.googleapis.com,cdnjs.cloudflare.com"
CSP_STYLE_SRC="'self',cdnjs.cloudflare.com"
CSP_STYLE_SRC_ELEM="'self',cdnjs.cloudflare.com"
CSP_FONT_SRC="'self',fonts.googleapis.com"
CSP_IMG_SRC="'self',data:"
CSP_FRAME_SRC="'self'"
CSP_BASE_URI="'self'"
CSP_REQUIRE_TRUSTED_TYPES_FOR=""
If you prefer not to use a third-party package, you can implement CSP using custom middleware.
class ContentSecurityPolicyMiddleware:
def process_request(self, request):
if not hasattr(request, 'csp_nonce'):
request.csp_nonce = uuid.uuid4().hex
def process_response(self, request, response):
nonce = getattr(request, 'csp_nonce', None)
if nonce:
csp_directives = {
'default-src': settings.CSP_DEFAULT_SRC,
'script-src': settings.CSP_SCRIPT_SRC,
'script-src-elem': settings.CSP_SCRIPT_SRC_ELEM,
'style-src': settings.CSP_STYLE_SRC,
'style-src-elem': settings.CSP_STYLE_SRC_ELEM,
'font-src': settings.CSP_FONT_SRC,
'img-src': settings.CSP_IMG_SRC,
'frame-src': settings.CSP_FRAME_SRC,
'base-uri': settings.CSP_BASE_URI,
'require-trusted-types-for': settings.CSP_REQUIRE_TRUSTED_TYPES_FOR,
}
for directive in ['script-src', 'script-src-elem', 'style-src', 'style-src-elem']:
if csp_directives.get(directive):
csp_directives[directive] = list(csp_directives[directive]) + [f"'nonce-{nonce}'"]
csp_header = '; '.join(
f"{directive} {' '.join(sources)}" for directive, sources in csp_directives.items() if sources)
response['Content-Security-Policy'] = csp_header
return response
settings.py
.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'yourapp.csp_middleware.ContentSecurityPolicyMiddleware',
# other middleware
]
CSP blocks inline scripts and styles by default. Use nonces or hashes to allow specific inline content.
The nonce are generated from above middleware and used in every templates files by `request.csp_nonce`
<script nonce="{{ request.csp_nonce }}">
console.log('This script is allowed by CSP.');
</script>
from django.utils.crypto import get_random_string
def add_nonce_to_context(request):
nonce = get_random_string(16)
request.csp_nonce = nonce
return nonce
response["Content-Security-Policy"] = f"script-src 'self' 'nonce-{nonce}';"
<script nonce="{{ request.csp_nonce }}">
console.log('This script is allowed by CSP.');
</script>
You can also allow specific inline scripts by calculating and including a hash of their content in the CSP header.
Content-Security-Policy: script-src 'self' 'sha256-xyz123...';
Enable CSP violation reporting to monitor and fine-tune your policies.
CSP_REPORT_URI = "https://your-server.com/csp-violation-report"
CSP_REPORT_ONLY = True # Test policies without enforcing them
Create an endpoint to handle violation reports and log them for analysis.
Implementing CSP in Django enhances your application's security and provides protection against common vulnerabilities.
Want to Explore more on Content security policy - A Shield Against Modern Web Vulnerabilities, Please visit