Compare commits

..

3 Commits

Author SHA1 Message Date
cc3f5d75ea
Optimized CSP 2025-05-19 10:05:30 +02:00
ab8b99b2c1
Solved path bug 2025-05-19 09:04:16 +02:00
35446b6d94
Solved variable bug 2025-05-19 08:45:25 +02:00
8 changed files with 57 additions and 8 deletions

View File

@ -120,6 +120,16 @@ class FilterModule(object):
): ):
tokens.append('https://www.google.com') 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 # whitelist
tokens += self.get_csp_whitelist(applications, application_id, directive) tokens += self.get_csp_whitelist(applications, application_id, directive)

View File

@ -9,12 +9,12 @@ defaults_service_provider:
city: "Cybertown" city: "Cybertown"
postal_code: "00001" postal_code: "00001"
country: "Nexusland" country: "Nexusland"
logo: "{{ applications.assets_server.url | safe_var | safe_join('logo.png') }}" logo: "{{ applications.assets_server.url | safe_var | safe_join('img/logo.png') }}"
platform: platform:
titel: "CyMaIS Demo" titel: "CyMaIS Demo"
subtitel: "The Future of Self-Hosted Infrastructure. Secure. Automated. Sovereign." subtitel: "The Future of Self-Hosted Infrastructure. Secure. Automated. Sovereign."
logo: "{{ applications.assets_server.url | safe_var | safe_join('logo.png') }}" logo: "{{ applications.assets_server.url | safe_var | safe_join('img/logo.png') }}"
favicon: "{{ applications.assets_server.url | safe_var | safe_join('favicon.ico') }}" favicon: "{{ applications.assets_server.url | safe_var | safe_join('img/favicon.ico') }}"
contact: contact:
bluesky: >- bluesky: >-
{{ ('@' ~ users.administrator.username ~ '.' ~ domains.bluesky.api) {{ ('@' ~ users.administrator.username ~ '.' ~ domains.bluesky.api)

View File

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

View File

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

View File

@ -13,3 +13,12 @@ features:
portfolio_iframe: false portfolio_iframe: false
central_database: true central_database: true
oauth2: 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 central_database: true
oauth2: true oauth2: true
hostname: central-mariadb hostname: central-mariadb
csp:
flags:
style-src:
unsafe-inline: true
script-src:
unsafe-inline: true

View File

@ -1,4 +1,4 @@
source_directory: "{{ playbook_dir }}/assets" # Directory from which the assets will be copied source_directory: "{{ playbook_dir }}/assets" # Directory from which the assets will be copied
url: >- url: >-
{{ (web_protocol ~ '://' ~ domains.file_server | safe_var ~ '/assets') {{ (web_protocol ~ '://' ~ domains.file_server | safe_var ~ '/assets')
if applications.assets_server.url | safe_var else '' }} if domains.file_server | safe_var else '' }}

View File

@ -167,5 +167,29 @@ class TestCspFilters(unittest.TestCase):
) )
self.assertNotIn("https://www.google.com", header_disabled) 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__': if __name__ == '__main__':
unittest.main() unittest.main()