Skip to content

Commit

Permalink
Add constants for CSP keywords
Browse files Browse the repository at this point in the history
This helps avoid potential errors introduced by incorrectly quoting CSP keywords.
  • Loading branch information
robhudson committed Jun 6, 2024
1 parent 3413de3 commit 90d9408
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 14 deletions.
10 changes: 10 additions & 0 deletions csp/constants.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
HEADER = "Content-Security-Policy"
HEADER_REPORT_ONLY = "Content-Security-Policy-Report-Only"

NONE = "'none'"
REPORT_SAMPLE = "'report-sample'"
SELF = "'self'"
STRICT_DYNAMIC = "'strict-dynamic'"
UNSAFE_ALLOW_REDIRECTS = "'unsafe-allow-redirects'"
UNSAFE_EVAL = "'unsafe-eval'"
UNSAFE_HASHES = "'unsafe-hashes'"
UNSAFE_INLINE = "'unsafe-inline'"
WASM_UNSAFE_EVAL = "'wasm-unsafe-eval'"
6 changes: 3 additions & 3 deletions csp/tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.test import RequestFactory
from django.test.utils import override_settings

from csp.constants import HEADER, HEADER_REPORT_ONLY
from csp.constants import HEADER, HEADER_REPORT_ONLY, SELF
from csp.middleware import CSPMiddleware
from csp.tests.utils import response

Expand All @@ -23,7 +23,7 @@ def test_add_header():

@override_settings(
CONTENT_SECURITY_POLICY={"DIRECTIVES": {"default-src": ["example.com"]}},
CONTENT_SECURITY_POLICY_REPORT_ONLY={"DIRECTIVES": {"default-src": ["'self'"]}},
CONTENT_SECURITY_POLICY_REPORT_ONLY={"DIRECTIVES": {"default-src": [SELF]}},
)
def test_both_headers():
request = rf.get("/")
Expand Down Expand Up @@ -51,7 +51,7 @@ def text_exclude():

@override_settings(
CONTENT_SECURITY_POLICY=None,
CONTENT_SECURITY_POLICY_REPORT_ONLY={"DIRECTIVES": {"default-src": ["'self'"]}},
CONTENT_SECURITY_POLICY_REPORT_ONLY={"DIRECTIVES": {"default-src": [SELF]}},
)
def test_report_only():
request = rf.get("/")
Expand Down
3 changes: 2 additions & 1 deletion csp/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.test.utils import override_settings
from django.utils.functional import lazy

from csp.constants import NONE, SELF
from csp.utils import build_policy, default_config, DEFAULT_DIRECTIVES


Expand Down Expand Up @@ -182,7 +183,7 @@ def test_replace_missing_setting():


def test_config():
policy = build_policy(config={"default-src": ["'none'"], "img-src": ["'self'"]})
policy = build_policy(config={"default-src": [NONE], "img-src": [SELF]})
policy_eq("default-src 'none'; img-src 'self'", policy)


Expand Down
3 changes: 2 additions & 1 deletion csp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
from django.conf import settings
from django.utils.encoding import force_str

from csp.constants import SELF

DEFAULT_DIRECTIVES = {
# Fetch Directives
"child-src": None,
"connect-src": None,
"default-src": ["'self'"],
"default-src": [SELF],
"script-src": None,
"script-src-attr": None,
"script-src-elem": None,
Expand Down
13 changes: 8 additions & 5 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ a more slightly strict policy and is used to test the policy without breaking th

.. code-block:: python
from csp.constants import NONE, SELF
CONTENT_SECURITY_POLICY = {
"EXCLUDE_URL_PREFIXES": ["/excluded-path/"],
"DIRECTIVES": {
"default-src": ["'self'", "cdn.example.net"],
"frame-ancestors": ["'self'"],
"form-action": ["'self'"],
"default-src": [SELF, "cdn.example.net"],
"frame-ancestors": [SELF],
"form-action": [SELF],
"report-uri": "/csp-report/",
},
}
Expand Down Expand Up @@ -101,8 +103,9 @@ policy.

.. note::
The "special" source values of ``'self'``, ``'unsafe-inline'``, ``'unsafe-eval'``,
``'none'`` and hash-source (``'sha256-...'``) must be quoted!
e.g.: ``"default-src": ["'self'"]``. Without quotes they will not work as intended.
``'strict-dynamic'``, ``'none'``, etc. must be quoted! e.g.: ``"default-src": ["'self'"]``.
Without quotes they will not work as intended. Use the ``csp.constants`` module to get these
values, e.g., ``from csp.constants import SELF``.

.. note::
Deprecated features of CSP in general have been moved to the bottom of this list.
Expand Down
9 changes: 5 additions & 4 deletions docs/decorators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,19 @@ If you need to set the entire policy on a view, ignoring all the settings, you c
decorator. This, and the other decorators, can be stacked to update both policies if both are in
use, as shown below. The arguments and values are as above::

from csp.constants import SELF, UNSAFE_INLINE
from csp.decorators import csp

@csp({
"default_src": ["'self'"],
"default_src": [SELF],
"img-src": ["imgsrv.com"],
"script-src": ["scriptsrv.com", "googleanalytics.com", "'unsafe-inline'"]}
"script-src": ["scriptsrv.com", "googleanalytics.com", UNSAFE_INLINE]}
})
@csp({
"default_src": ["'self'"],
"default_src": [SELF],
"img-src": ["imgsrv.com"],
"script-src": ["scriptsrv.com", "googleanalytics.com"]},
"frame-src": ["'self'"],
"frame-src": [SELF],
REPORT_ONLY=True
})
def myview(request):
Expand Down

0 comments on commit 90d9408

Please sign in to comment.