Optimized CSP rules

This commit is contained in:
Kevin Veen-Birkenbach 2025-06-03 14:32:15 +02:00
parent cc9b634bb8
commit ebd74db3c4
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
27 changed files with 57 additions and 39 deletions

View File

@ -109,7 +109,7 @@ class FilterModule(object):
# Matomo integration # Matomo integration
if ( if (
self.is_feature_enabled(applications, matomo_feature_name, application_id) self.is_feature_enabled(applications, matomo_feature_name, application_id)
and directive in ['script-src', 'connect-src'] and directive in ['script-src-elem', 'connect-src']
): ):
matomo_domain = domains.get('matomo')[0] matomo_domain = domains.get('matomo')[0]
if matomo_domain: if matomo_domain:
@ -117,10 +117,9 @@ class FilterModule(object):
# ReCaptcha integration: allow loading scripts from Google if feature enabled # ReCaptcha integration: allow loading scripts from Google if feature enabled
if self.is_feature_enabled(applications, 'recaptcha', application_id): if self.is_feature_enabled(applications, 'recaptcha', application_id):
if directive == 'script-src':
tokens.append('https://www.google.com')
if directive == 'script-src-elem': if directive == 'script-src-elem':
tokens.append('https://www.gstatic.com') tokens.append('https://www.gstatic.com')
tokens.append('https://www.google.com')
# Enable loading via ancestors # Enable loading via ancestors
if ( if (

View File

@ -17,7 +17,7 @@ domains:
- "meet.{{ primary_domain }}" - "meet.{{ primary_domain }}"
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
style-src: style-src:
unsafe-inline: true unsafe-inline: true

View File

@ -12,7 +12,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
whitelist: whitelist:
font-src: font-src:

View File

@ -15,7 +15,7 @@ features:
central_database: true central_database: true
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
style-src: style-src:

View File

@ -12,7 +12,7 @@ features:
central_database: true central_database: true
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
style-src: style-src:
unsafe-inline: true unsafe-inline: true

View File

@ -14,7 +14,7 @@ features:
recaptcha: true recaptcha: true
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
style-src: style-src:
unsafe-inline: true unsafe-inline: true

View File

@ -15,7 +15,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
domains: domains:

View File

@ -7,7 +7,7 @@ public_api_activated: False # Security hol
version: "latest" # Docker Image version version: "latest" # Docker Image version
features: features:
matomo: true matomo: true
css: true css: false
portfolio_iframe: true portfolio_iframe: true
central_database: true central_database: true
oidc: true oidc: true

View File

@ -16,8 +16,9 @@ features:
domains: domains:
canonical: canonical:
- "mail.{{ primary_domain }}" - "mail.{{ primary_domain }}"
flags: csp:
flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true

View File

@ -8,12 +8,12 @@ features:
oauth2: false oauth2: false
csp: csp:
whitelist: whitelist:
script-src: script-src-elem:
- https://cdn.matomo.cloud - https://cdn.matomo.cloud
style-src: style-src:
- https://fonts.googleapis.com - https://fonts.googleapis.com
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
style-src: style-src:

View File

@ -20,7 +20,7 @@ features:
central_database: true central_database: true
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
style-src: style-src:
@ -29,7 +29,7 @@ csp:
connect-src: connect-src:
- "{{ primary_domain }}" - "{{ primary_domain }}"
- "matrix.{{ primary_domain }}" - "matrix.{{ primary_domain }}"
script-src: script-src-elem:
- "element.{{ primary_domain }}" - "element.{{ primary_domain }}"
- "https://cdn.jsdelivr.net" - "https://cdn.jsdelivr.net"
plugins: plugins:

View File

@ -12,7 +12,7 @@ features:
oidc: false oidc: false
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
style-src: style-src:
@ -21,7 +21,7 @@ csp:
font-src: font-src:
- "data:" - "data:"
- "blob:" - "blob:"
script-src: script-src-elem:
- "https://cdn.jsdelivr.net" - "https://cdn.jsdelivr.net"
domains: domains:
canonical: canonical:

View File

@ -0,0 +1,13 @@
# Update Nextcloud (manuel)
To perform a manuel Nexcloud update execute:
```bash
docker-compose exec -T -u www-data application /var/www/html/occ upgrade
docker-compose exec -T -u www-data application /var/www/html/occ maintenance:repair --include-expensive
docker-compose exec -T -u www-data application /var/www/html/occ app:update --all
docker-compose exec -T -u www-data application /var/www/html/occ db:add-missing-columns
docker-compose exec -T -u www-data application /var/www/html/occ db:add-missing-indices
docker-compose exec -T -u www-data application /var/www/html/occ db:add-missing-primary-keys
docker-compose exec -T -u www-data application /var/www/html/occ maintenance:mode --off
```

View File

@ -3,7 +3,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
whitelist: whitelist:
font-src: font-src:

View File

@ -15,7 +15,7 @@ features:
oauth2: true oauth2: true
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
style-src: style-src:
unsafe-inline: true unsafe-inline: true

View File

@ -7,7 +7,7 @@ features:
oidc: true oidc: true
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
style-src: style-src:
unsafe-inline: true unsafe-inline: true

View File

@ -17,7 +17,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
whitelist: whitelist:
font-src: font-src:

View File

@ -14,7 +14,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
domains: domains:
aliases: aliases:

View File

@ -7,7 +7,7 @@ features:
central_database: true central_database: true
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
style-src: style-src:

View File

@ -4,7 +4,7 @@ features:
portfolio_iframe: false portfolio_iframe: false
csp: csp:
whitelist: whitelist:
script-src: script-src-elem:
- https://cdn.jsdelivr.net - https://cdn.jsdelivr.net
- https://kit.fontawesome.com - https://kit.fontawesome.com
style-src: style-src:
@ -19,7 +19,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
domains: domains:
canonical: canonical:

View File

@ -5,7 +5,7 @@ features:
csp: csp:
whitelist: whitelist:
script-src: script-src-elem:
- https://cdnjs.cloudflare.com - https://cdnjs.cloudflare.com
- https://code.jquery.com - https://code.jquery.com
- https://cdn.jsdelivr.net - https://cdn.jsdelivr.net
@ -17,7 +17,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-eval: true unsafe-eval: true
domains: domains:
canonical: canonical:

View File

@ -9,7 +9,7 @@ domains:
- "inventory.{{ primary_domain }}" - "inventory.{{ primary_domain }}"
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
style-src: style-src:
unsafe-inline: true unsafe-inline: true

View File

@ -4,7 +4,7 @@ features:
portfolio_iframe: false portfolio_iframe: false
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
style-src: style-src:

View File

@ -15,7 +15,7 @@ features:
csp: csp:
flags: flags:
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
style-src: style-src:

View File

@ -20,7 +20,7 @@ csp:
flags: flags:
style-src: style-src:
unsafe-inline: true unsafe-inline: true
script-src: script-src-elem:
unsafe-inline: true unsafe-inline: true
unsafe-eval: true unsafe-eval: true
whitelist: whitelist:
@ -29,7 +29,7 @@ csp:
font-src: font-src:
- "data:" - "data:"
- "https://fonts.bunny.net" - "https://fonts.bunny.net"
script-src: script-src-elem:
- "https://cdn.gtranslate.net" - "https://cdn.gtranslate.net"
- "blog.{{ primary_domain }}" - "blog.{{ primary_domain }}"
style-src: style-src:

View File

@ -10,6 +10,7 @@ class TestCspConfigurationConsistency(unittest.TestCase):
'frame-ancestors', 'frame-ancestors',
'frame-src', 'frame-src',
'script-src', 'script-src',
'script-src-elem',
'style-src', 'style-src',
'font-src', 'font-src',
'worker-src', 'worker-src',

View File

@ -24,7 +24,7 @@ class TestCspFilters(unittest.TestCase):
}, },
'csp': { 'csp': {
'whitelist': { 'whitelist': {
'script-src': ['https://cdn.example.com'], 'script-src-elem': ['https://cdn.example.com'],
'connect-src': 'https://api.example.com', 'connect-src': 'https://api.example.com',
}, },
'flags': { 'flags': {
@ -53,7 +53,7 @@ class TestCspFilters(unittest.TestCase):
} }
def test_get_csp_whitelist_list(self): def test_get_csp_whitelist_list(self):
result = self.filter.get_csp_whitelist(self.apps, 'app1', 'script-src') result = self.filter.get_csp_whitelist(self.apps, 'app1', 'script-src-elem')
self.assertEqual(result, ['https://cdn.example.com']) self.assertEqual(result, ['https://cdn.example.com'])
def test_get_csp_whitelist_string(self): def test_get_csp_whitelist_string(self):
@ -84,7 +84,11 @@ class TestCspFilters(unittest.TestCase):
self.assertIn("default-src 'self';", header) self.assertIn("default-src 'self';", header)
# script-src directive should include unsafe-eval, Matomo domain and CDN (hash may follow) # script-src directive should include unsafe-eval, Matomo domain and CDN (hash may follow)
self.assertIn( self.assertIn(
"script-src 'self' 'unsafe-eval' https://matomo.example.org https://cdn.example.com", "script-src-elem 'self' https://matomo.example.org https://cdn.example.com",
header
)
self.assertIn(
"script-src 'self' 'unsafe-eval'",
header header
) )
# connect-src directive unchanged (no inline hash) # connect-src directive unchanged (no inline hash)