Comments (1)
from csp.utils import build_policy, get_nonce_generator
def custom_build_policy(
policies, overrides=None, nonce_generator=get_nonce_generator(),
report_only=False):
# Include your custom logic here to manipulate policies and overrides as desired
csp = build_policy(policies, overrides=overrides, report_only=report_only)
return csp
def construct_final_string(policy_parts):
# Include your custom logic here to construct the final string
# based on policy_parts
final = "; ".join(policy_parts)
final = " ".join([final, "report-uri /csp_reports/"])
return final
def add_nonce(policy, source):
# Include logic here to add a nonce to the specified source if necessary
return source
# Update the original build_policy function to call the new functions
def build_policy(policies, overrides=None, nonce_generator=get_nonce_generator(),
report_only=False):
policy_parts = []
for policy in policies:
for name, value in policy.items():
# Handle the nonce directive here
if name == 'nonce':
continue
elif name in ('default-src', 'script-src', 'style-src', 'img-src', 'connect-src',
'font-src','media-src', 'object-src', 'child-src', 'frame-src', 'worker-src',
'manifest-src', 'base-uri', 'form-action', 'frame-ancestors',
'plugin-types', 'sandbox', 'navigate-to', 'block-all-mixed-content',
'upgrade-insecure-requests', 'require-sri-for'):
# Split multiple directives where necessary
values = [v.strip() for v in value.split(';') if v.strip()]
# Add nonces to sources if necessary
if nonce_generator and name in ('script-src', 'style-src', 'default-src'):
values = [add_nonce(policy, v) if 'nonce' not in v else v for v in values]
# Append the directive with its values
policy_parts.append(' '.join([name] + values))
final = construct_final_string(policy_parts)
return final
The custom_build_policy function takes a list of policy dictionaries and some optional arguments, and returns a CSP header string. The build_policy function is called by custom_build_policy and constructs the policy header by iterating over the policy dictionaries and their key-value pairs.
The construct_final_string function takes a list of policy strings and constructs the final CSP header string by joining them together with semicolons and adding a report URI.
The add_nonce function is called by build_policy for certain policy types and adds a nonce value to the allowed sources to prevent script injection attacks.
from django.test import TestCase, RequestFactory
from django.http import HttpResponse
from django.urls import reverse
from django_csp.middleware import CSPMiddleware
class CSPMiddlewareTests(TestCase):
def setUp(self):
self.factory = RequestFactory()
def test_can_process_request(self):
request = self.factory.get(reverse('home'))
middleware = CSPMiddleware(None)
response = middleware.process_request(request)
self.assertIsNone(response)
def test_can_pre_process_response_with_empty_policy(self):
request = self.factory.get(reverse('home'))
middleware = CSPMiddleware(lambda r: HttpResponse())
response = middleware(request)
self.assertIn('Content-Security-Policy', response)
self.assertEqual(response['Content-Security-Policy'], "default-src 'self'")
def test_can_pre_process_response_with_non_empty_policy(self):
request = self.factory.get(reverse('home'))
middleware = CSPMiddleware(lambda r: HttpResponse())
middleware.policy = {'default-src': ['www.example.com', 'maxcdn.bootstrapcdn.com']}
response = middleware(request)
self.assertIn('Content-Security-Policy', response)
self.assertEqual(response['Content-Security-Policy'], "default-src www.example.com maxcdn.bootstrapcdn.com")
To allow editing of the build policy layout for django-csp, you can modify the build_policy
function to return the csp
variable before it is changed into policy_parts
.
You can then refactor the addition of nonce and final string construction into new functions, such as add_nonce_to_policy
and construct_csp_header
, respectively. These functions can be called by build_policy
to add the nonce and construct the final CSP header string.
Developers can then hook into the output of build_policy
to order or append policy parts as required, and then return the outputs of add_nonce_to_policy
and construct_csp_header
as required.
Here's an example implementation:
def build_policy(policies, overrides=None, nonce_generator=get_nonce_generator(),
report_only=False):
csp = {}
for policy in policies:
for name, value in policy.items():
if name == 'nonce':
continue
elif name in ('default-src', 'script-src', 'style-src', 'img-src', 'connect-src',
'font-src','media-src', 'object-src', 'child-src', 'frame-src', 'worker-src',
'manifest-src', 'base-uri', 'form-action', 'frame-ancestors',
'plugin-types', 'sandbox', 'navigate-to', 'block-all-mixed-content',
'upgrade-insecure-requests', 'require-sri-for'):
values = [v.strip() for v in value.split(';') if v.strip()]
if nonce_generator and name in ('script-src', 'style-src', 'default-src'):
values = [add_nonce(policy, v) if 'nonce' not in v else v for v in values]
csp[name] = values
return csp
def add_nonce_to_policy(policy, source):
return source
def construct_csp_header(policy_parts):
final = "; ".join(policy_parts)
final = " ".join([final, "report-uri /csp_reports/"])
return final
from django.test import TestCase
from django_csp.utils import build_policy
class BuildPolicyTestCase(TestCase):
def test_build_policy(self):
policies = [
{'default-src': "'self'"},
{'script-src': "'self'"},
{'style-src': "'self'"},
{'img-src': "'self'"},
]
overrides = {'script-src': "'unsafe-inline'"}
csp = build_policy(policies, overrides=overrides)
expected_csp = {
'default-src': ["'self'"],
'script-src': ["'self'", "'unsafe-inline'"],
'style-src': ["'self'"],
'img-src': ["'self'"],
}
self.assertEqual(csp, expected_csp)
This test case creates a list of policies and an override for the script-src policy. It then calls the build_policy function with these policies and the override, and compares the resulting CSP with the expected CSP. This test ensures that the build_policy function correctly combines the policies and applies the override.
You can then use these functions in your Django views or middleware to generate customized CSP headers.
from django-csp.
Related Issues (20)
- 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
- Don't include nonces in default-src when CSP_INCLUDE_NONCE_IN is unset / an empty list HOT 3
- 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
- Change import path to `django_csp` - breaking change HOT 1
- docs: Differentiate between "None" and `NONE` in directives
- [Beta] Report percentage cannot be smaller than 1% HOT 2
- When REPORT_PERCENTAGE is set to 100%, the `report-uri` directive is not always included in the CSP header HOT 2
- docs: Add that `REPORT_PERCENTAGE` requires the rate-limiting middleware in the configuration docs
- Add support for reporting endpoints headers
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.