Skip to content

Commit 38f036d

Browse files
author
Rob Hudson
committed
Prep for 4.0 release
1 parent 9d06e25 commit 38f036d

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

CHANGES.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,156 @@
11
CHANGES
22
=======
33

4+
4.0
5+
===
6+
7+
This release contains several breaking changes. For a complete migration guide, see:
8+
https://django-csp.readthedocs.io/en/latest/migration-guide.html
9+
10+
## Breaking Changes
11+
12+
- **Configuration Format**: Moved to dict-based configuration which allows for setting policies for
13+
both enforced and report-only. Instead of using individual settings with `CSP_` prefixes, you now use
14+
dictionaries called `CONTENT_SECURITY_POLICY` and/or `CONTENT_SECURITY_POLICY_REPORT_ONLY`.
15+
16+
**Example:**
17+
18+
Change from:
19+
```python
20+
CSP_DEFAULT_SRC = ["'self'", "*.example.com"]
21+
CSP_SCRIPT_SRC = ["'self'", "js.cdn.com/example/"]
22+
CSP_IMG_SRC = ["'self'", "data:", "example.com"]
23+
CSP_EXCLUDE_URL_PREFIXES = ["/admin"]
24+
```
25+
26+
to:
27+
```python
28+
from csp.constants import SELF
29+
30+
CONTENT_SECURITY_POLICY = {
31+
"EXCLUDE_URL_PREFIXES": ["/admin"],
32+
"DIRECTIVES": {
33+
"default-src": [SELF, "*.example.com"],
34+
"script-src": [SELF, "js.cdn.com/example/"],
35+
"img-src": [SELF, "data:", "example.com"],
36+
},
37+
}
38+
```
39+
40+
- **Nonce Configuration**: Switched from specifying directives that should contain nonces as a
41+
separate list to using a sentinel `NONCE` value in the directive itself.
42+
43+
**Example:**
44+
45+
Change from:
46+
```python
47+
CSP_INCLUDE_NONCE_IN = ['script-src', 'style-src']
48+
```
49+
50+
to:
51+
```python
52+
from csp.constants import NONCE, SELF
53+
54+
CONTENT_SECURITY_POLICY = {
55+
"DIRECTIVES": {
56+
"script-src": [SELF, NONCE],
57+
"style-src": [SELF, NONCE],
58+
}
59+
}
60+
```
61+
62+
- **Nonce Behavior**: Changed how `request.csp_nonce` works - it is now Falsy
63+
(`bool(request.csp_nonce)`) until it is read as a string (e.g., used in a template or with
64+
`str(request.csp_nonce)`). Previously, it always tested as `True`, and testing generated the nonce.
65+
66+
**Before:**
67+
```python
68+
# The nonce was generated when this was evaluated
69+
if request.csp_nonce:
70+
# Do something with nonce
71+
```
72+
73+
**After:**
74+
```python
75+
# This won't generate the nonce, and will evaluate to False until nonce is read as a string
76+
if request.csp_nonce:
77+
# This code won't run until nonce is used as a string
78+
79+
# To generate and use the nonce
80+
nonce_value = str(request.csp_nonce)
81+
```
82+
83+
- Dropped support for Django ≤3.2.
84+
- Dropped support for Python 3.8.
85+
86+
## New Features and Improvements
87+
88+
- **Dual Policy Support**: Added support for enforced and report-only policies simultaneously using
89+
the separate `CONTENT_SECURITY_POLICY` and `CONTENT_SECURITY_POLICY_REPORT_ONLY` settings.
90+
91+
**Example:**
92+
```python
93+
from csp.constants import NONE, SELF
94+
95+
# Enforced policy
96+
CONTENT_SECURITY_POLICY = {
97+
"DIRECTIVES": {
98+
"default-src": [SELF, "cdn.example.net"],
99+
"frame-ancestors": [SELF],
100+
},
101+
}
102+
103+
# Report-only policy (stricter for testing)
104+
CONTENT_SECURITY_POLICY_REPORT_ONLY = {
105+
"DIRECTIVES": {
106+
"default-src": [NONE],
107+
"script-src": [SELF],
108+
"style-src": [SELF],
109+
"report-uri": "/csp-report/",
110+
},
111+
}
112+
```
113+
114+
- **CSP Constants**: Added CSP keyword constants in `csp.constants` (e.g., `SELF` instead of
115+
`"'self'"`) to minimize quoting mistakes and typos.
116+
117+
**Example:**
118+
119+
Change from:
120+
```python
121+
CSP_DEFAULT_SRC = ["'self'", "'none'"]
122+
```
123+
124+
to:
125+
```python
126+
from csp.constants import SELF, NONE
127+
128+
CONTENT_SECURITY_POLICY = {
129+
"DIRECTIVES": {
130+
"default-src": [SELF, NONE], # No need to worry about quoting
131+
}
132+
}
133+
```
134+
135+
- Added comprehensive type hints.
136+
- Added `EXCLUDE_URL_PREFIXES` check.
137+
- Added support for CSP configuration as sets.
138+
- Changed `REPORT_PERCENTAGE` to allow floats (e.g., for values < 1%) and improved behavior for 100%
139+
report percentage to always send CSP reports.
140+
- Added ability to read the nonce after response if it was included in the header. This will raise
141+
an error when nonce is accessed after response if not already generated.
142+
- Made changes to simplify middleware logic and make `CSPMiddleware` easier to subclass. The updated
143+
middleware returns a PolicyParts dataclass that can be modified before the policy is built.
144+
145+
## Other Changes
146+
147+
- Added Python 3.13 support.
148+
- Added support for Django 5.1 and 5.2.
149+
- Documentation improvements including fixed trusted_types links and clarification on NONE vs Python's None.
150+
- Documentation note that reporting percentage needs rate limiting middleware.
151+
- Expanded ruff configuration and moved into pyproject.toml.
152+
153+
4154
4.0b7
5155
=====
6156
- Removed ``CSPMiddlewareAlwaysGenerateNonce`` middleware that forced nonce headers when not used in

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ requires = [ "setuptools>=61.2" ]
44

55
[project]
66
name = "django-csp"
7-
version = "4.0b7"
7+
version = "4.0"
88
description = "Django Content Security Policy support."
99
readme = "README.rst"
1010
license = { text = "BSD" }

0 commit comments

Comments
 (0)