Optimized CSP

This commit is contained in:
Kevin Veen-Birkenbach 2025-05-19 10:05:30 +02:00
parent ab8b99b2c1
commit cc3f5d75ea
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
6 changed files with 53 additions and 4 deletions

View File

@ -120,6 +120,16 @@ class FilterModule(object):
):
tokens.append('https://www.google.com')
# Enable loading via ancestors
if (
self.is_feature_enabled(applications, 'portfolio_iframe', application_id)
and directive == 'frame-ancestors'
):
domain = domains.get(application_id) # e.g. "sub.example.com" or "example.com"
# Extract the second-level + top-level domain and prefix with "*."
sld_tld = ".".join(domain.split(".")[-2:]) # yields "example.com"
tokens.append(f"*.{sld_tld}") # yields "*.example.com"
# whitelist
tokens += self.get_csp_whitelist(applications, application_id, directive)

View File

@ -6,7 +6,7 @@ import_realm: True # If True realm will b
credentials:
features:
matomo: true
css: true
css: false
portfolio_iframe: true
ldap: true
central_database: true

View File

@ -1,7 +1,7 @@
version: "bookworm"
features:
matomo: true
css: true
css: false
portfolio_iframe: false
central_database: true
csp:

View File

@ -13,3 +13,12 @@ features:
portfolio_iframe: false
central_database: true
oauth2: true
csp:
flags:
style-src:
unsafe-inline: true
script-src:
unsafe-inline: true
whitelist:
font-src:
- "data:"

View File

@ -10,3 +10,9 @@ features:
central_database: true
oauth2: true
hostname: central-mariadb
csp:
flags:
style-src:
unsafe-inline: true
script-src:
unsafe-inline: true

View File

@ -167,5 +167,29 @@ class TestCspFilters(unittest.TestCase):
)
self.assertNotIn("https://www.google.com", header_disabled)
def test_build_csp_header_frame_ancestors(self):
"""
frame-ancestors should include the wildcarded SLD+TLD when
'portfolio_iframe' is enabled, and omit it when disabled.
"""
# Ensure feature enabled and domain set
self.apps['app1']['features']['portfolio_iframe'] = True
# simulate a subdomain for the application
self.domains['app1'] = 'sub.domain-example.com'
header = self.filter.build_csp_header(self.apps, 'app1', self.domains, web_protocol='https')
# Expect '*.domain-example.com' in the frame-ancestors directive
self.assertRegex(
header,
r"frame-ancestors\s+'self'\s+\*\.domain-example\.com;"
)
# Now disable the feature and rebuild
self.apps['app1']['features']['portfolio_iframe'] = False
header_no = self.filter.build_csp_header(self.apps, 'app1', self.domains, web_protocol='https')
# Should no longer contain the wildcarded sld.tld
self.assertNotIn("*.domain-example.com", header_no)
if __name__ == '__main__':
unittest.main()