Comments (3)
To exclude nonces from the default-src when CSP_INCLUDE_NONCE_IN is unset or an empty list, we need to modify the CSPMiddleware class of django-csp.
We can modify the _build_policy method of the CSPMiddleware class to conditionally include nonces in the default-src directive based on whether CSP_INCLUDE_NONCE_IN is set. If it is, we include the nonce in the specified directive, and if not, we exclude it.
Here is an updated version of the _build_policy method that implements this behavior:
def _build_policy(self, nonce=None):
cspsettings = {key[len('CSP'):]: value for key, value in getattr(settings, 'CSP_CONFIG', {}).items()}
policy = {}
# Add directives that aren't on by default
for directive in self.directives:
if directive in csp_settings:
policy[directive] = csp_settings[directive]
# Add directives that are on by default
for directive in self.default_on_directives:
# Check whether we should include nonces in this directive
if 'CSP_INCLUDE_NONCE_IN' in getattr(settings, 'CSP_CONFIG', {}):
include_nonce = self.directive_matches(directive, getattr(settings, 'CSP_CONFIG', {})['CSP_INCLUDE_NONCE_IN'])
if directive not in policy:
# By default, the following default-src is always set
if directive == 'default-src':
if include_nonce:
policy[directive] = "'self' 'unsafe-inline' 'unsafe-eval'; base-uri 'self'; form-action 'self'"
else:
policy[directive] = "'self' 'unsafe-inline' 'unsafe-eval'; base-uri 'self'; form-action 'self';nonce-{0}".format(nonce)
else:
# Append nonce to other directives that support it
if include_nonce:
policy[directive] = "'self' 'unsafe-inline' 'unsafe-eval'; base-uri 'self'; form-action 'self';nonce-{0}".format(nonce)
else:
policy[directive] = "'self' 'unsafe-inline' 'unsafe-eval'; base-uri 'self'; form-action 'self'"
for directive in self.default_src_directives:
# Check whether we should include nonces in this directive
if 'CSP_INCLUDE_NONCE_IN' in getattr(settings, 'CSP_CONFIG', {}):
include_nonce = self.directive_matches(directive, getattr(settings, 'CSP_CONFIG', {})['CSP_INCLUDE_NONCE_IN'])
# Only include 'self' directive in default-src if not including a nonce in it
if directive == 'self' and not include_nonce:
continue
# Append nonce to default-src if including nonces in it
if include_nonce:
policy['default-src'] += " 'nonce-{0}'".format(nonce)
else:
policy['default-src'] += " '{0}'".format(directive)
return policy
from django.test import RequestFactory, TestCase
from django.http import HttpResponse
from django.urls import reverse
from django_csp.middleware import CSPMiddleware
from myapp.views import MyView
class CSPMiddlewareTest(TestCase):
def setUp(self):
self.factory = RequestFactory()
def test_process_request_with_CSP(self):
# Create a request object and a response object
request = self.factory.get('/my-view/')
response = HttpResponse()
# Create a middleware object and call the process_request method
middleware = CSPMiddleware(get_response=None)
result = middleware.process_request(request)
# Verify that the process_request method returns None since the response object does not have a CSP header yet
self.assertIsNone(result)
# Call the process_response method and verify that the response object now has a CSP header
middleware.process_response(request, response)
self.assertTrue('Content-Security-Policy' in response)
def test_process_request_exempt_from_CSP(self):
# Create a request object that should be exempt from CSP
request = self.factory.get('/my-view/')
# Create a response object with the CSP header
response = HttpResponse()
middleware = CSPMiddleware(get_response=None)
response['Content-Security-Policy'] = middleware._build_policy({})
# Set the exempt_urls attribute to include the URL path of the request object
middleware.exempt_urls = ['/my-view/']
# Verify that the process_request method returns None since the URL path of the request is exempt from CSP
self.assertIsNone(middleware.process_request(request))
def test_process_response_with_CSP_decorator(self):
# Create a request object and a response object
request = self.factory.get(reverse('my-view'))
To modify django-csp to exclude nonces from default-src when CSP_INCLUDE_NONCE_IN is unset or an empty list, you can modify the get_nonce_included_directives function in csp/utils.py as follows:
def get_nonce_included_directives(include_nonce_in):
"""
Returns a list of directives that should include nonces.
"""
if not include_nonce_in:
return []
if include_nonce_in == ['default-src']:
return ['default-src']
return include_nonce_in + ['default-src']
This modified function checks if include_nonce_in is unset or an empty list, and returns an empty list if so. Otherwise, it returns include_nonce_in plus 'default-src', which excludes the nonce from the default-src directive.
from django.test import TestCase
from mozilla.django_csp.utils import get_nonce_included_directives
class GetNonceIncludedDirectivesTestCase(TestCase):
"""
Test case for the get_nonce_included_directives() utility function.
"""
def test_empty_include_nonce_in(self):
"""
Test for when include_nonce_in is an empty list.
"""
result = get_nonce_included_directives([])
self.assertEqual(result, [])
def test_default_src_included(self):
"""
Test for when include_nonce_in is ['default-src'].
"""
result = get_nonce_included_directives(['default-src'])
self.assertEqual(result, ['default-src'])
def test_other_directives_included(self):
"""
Test for when include_nonce_in contains other directives besides 'default-src'.
"""
result = get_nonce_included_directives(['script-src', 'style-src'])
self.assertEqual(result, ['script-src', 'style-src', 'default-src'])
def test_none_include_nonce_in(self):
"""
Test for when include_nonce_in is None.
"""
result = get_nonce_included_directives(None)
self.assertEqual(result, ['default-src'])
from django-csp.
Related Issues (20)
- nonce, request.csp_nonce and {% script %} all fail to render a nonce HOT 8
- Documentation needs to be updated to mention INSTALLED_APPS HOT 4
- Decorators depending on request method types HOT 3
- broken admin filters HOT 3
- Modify CSP based on database? HOT 1
- `CSP_INCLUDE_NONCE_IN` not working? HOT 4
- New release? HOT 11
- State of project HOT 9
- Unrecognized Content Security Policy directive 'worker-src' in Safari Browser HOT 2
- Building the wheel doesn't work HOT 4
- Backwards compatible method of adding 'strict-dynamic' as suffix HOT 1
- Allow direct editing of build policy output HOT 1
- Documentation for context processor HOT 5
- Deprecated Features HOT 5
- interested in adding typing (mypy) support? HOT 4
- Support clearing/unsetting directives via decorator HOT 7
- Support different sets of rules for paths like /admin HOT 8
- Move project to pyproject.toml HOT 1
- Create csp.extensions.NoncedStyle extension HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-csp.