Skip to content

Commit

Permalink
Merge pull request PGScatalog#406 from PGScatalog/fix/csp_nonce_cache
Browse files Browse the repository at this point in the history
Fix CSP "nonce" not being refreshed if the page is loaded from backend cache
  • Loading branch information
fyvon authored Jan 22, 2025
2 parents a951d15 + 5c286e0 commit c2c02ab
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
24 changes: 24 additions & 0 deletions catalog/cache/remove_nonce.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from django.core.cache.backends.locmem import LocMemCache
import re


class RemoveNonceFromCacheBackend(LocMemCache):
"""If a page is cached on the server and contains CSP nonces, the value of the nonce
if not refreshed making it not matching the nonce any new HTTP response header, and
more problematically giving the same nonce to all clients. This subclass removes
the nonce completely from a cached page, which will be put back downstream by the
middleware with the correct value of the new request."""
def get(self, key, default=None, version=None):
result = super().get(key, default, version)
if result is not None:
if (key.startswith('views.decorators.cache.cache_page')
and hasattr(result, 'content')
and 'text/html' in result.get('Content-Type', '')):
# Remove every html nonce="..." attribute from cached content
result.content = re.sub(
r' nonce="[^"]+"',
'',
result.content.decode('utf-8'),
flags=re.IGNORECASE
).encode('utf-8')
return result
7 changes: 7 additions & 0 deletions pgs_web/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ def get_base_url(full_url):
'csp.middleware.CSPMiddleware',
'catalog.middleware.add_nonce.AddNonceToScriptsMiddleware'
])
CACHES = {
'default': {
# Custom cache class called if cache_page decorator is used
'BACKEND': 'catalog.cache.remove_nonce.RemoveNonceFromCacheBackend',
}
}

CSP_INCLUDE_NONCE_IN = [
'script-src'
Expand Down Expand Up @@ -152,6 +158,7 @@ def get_base_url(full_url):
)
# front-src
CSP_FONT_SRC = ("'self'",
"data:",
get_base_url(STYLES_URLS['font-awesome']),
get_base_url(STYLES_URLS['ebi']))
# connect-src
Expand Down

0 comments on commit c2c02ab

Please sign in to comment.