Solved unsafe inline bug

This commit is contained in:
Kevin Veen-Birkenbach 2025-05-15 10:04:34 +02:00
parent 779c60ef20
commit 6b7314baac
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
7 changed files with 28 additions and 9 deletions

View File

@ -97,8 +97,11 @@ class FilterModule(object):
for directive in directives: for directive in directives:
tokens = ["'self'"] tokens = ["'self'"]
# unsafe-eval / unsafe-inline flags # unsafe-eval / unsafe-inline flags
tokens += self.get_csp_flags(applications, application_id, directive) flags = self.get_csp_flags(applications, application_id, directive)
tokens += flags
# 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)
@ -107,11 +110,15 @@ class FilterModule(object):
matomo_domain = domains.get('matomo') matomo_domain = domains.get('matomo')
if matomo_domain: if matomo_domain:
tokens.append(f"{web_protocol}://{matomo_domain}") tokens.append(f"{web_protocol}://{matomo_domain}")
# whitelist # whitelist
tokens += self.get_csp_whitelist(applications, application_id, directive) tokens += self.get_csp_whitelist(applications, application_id, directive)
# inline hashes from config
for snippet in self.get_csp_inline_content(applications, application_id, directive): # only add hashes if 'unsafe-inline' is NOT in flags
tokens.append(self.get_csp_hash(snippet)) if "'unsafe-inline'" not in flags:
for snippet in self.get_csp_inline_content(applications, application_id, directive):
tokens.append(self.get_csp_hash(snippet))
parts.append(f"{directive} {' '.join(tokens)};") parts.append(f"{directive} {' '.join(tokens)};")
# static img-src # static img-src

View File

@ -14,6 +14,7 @@
- name: Set fact for backup_docker_to_local_folder - name: Set fact for backup_docker_to_local_folder
set_fact: set_fact:
backup_docker_to_local_folder: "{{ pkgmgr_output.stdout }}/" backup_docker_to_local_folder: "{{ pkgmgr_output.stdout }}/"
changed_when: false
when: run_once_backup_docker_to_local is not defined when: run_once_backup_docker_to_local is not defined
- name: configure backup-docker-to-local-everything.cymais.service - name: configure backup-docker-to-local-everything.cymais.service

View File

@ -14,6 +14,7 @@
- name: Set fact for backup_docker_to_local_cleanup_script - name: Set fact for backup_docker_to_local_cleanup_script
set_fact: set_fact:
backup_docker_to_local_cleanup_script: "{{ pkgmgr_output.stdout.rstrip('/') ~ '/cleanup-all.sh' }}" backup_docker_to_local_cleanup_script: "{{ pkgmgr_output.stdout.rstrip('/') ~ '/cleanup-all.sh' }}"
changed_when: false
when: run_once_cleanup_failed_docker_backups is not defined when: run_once_cleanup_failed_docker_backups is not defined
- name: configure cleanup-failed-docker-backups.cymais.service - name: configure cleanup-failed-docker-backups.cymais.service

View File

@ -24,10 +24,12 @@
debug: "{{ enable_debug | default(false) }}" debug: "{{ enable_debug | default(false) }}"
register: cert_folder_result register: cert_folder_result
delegate_to: "{{ inventory_hostname }}" delegate_to: "{{ inventory_hostname }}"
changed_when: false
- name: Set fact - name: Set fact
set_fact: set_fact:
ssl_cert_folder: "{{ cert_folder_result.folder }}" ssl_cert_folder: "{{ cert_folder_result.folder }}"
changed_when: false
- name: Ensure ssl_cert_folder is set - name: Ensure ssl_cert_folder is set
fail: fail:

View File

@ -25,6 +25,7 @@
set_fact: set_fact:
matomo_site_id: "{{ site_check.json[0].idsite }}" matomo_site_id: "{{ site_check.json[0].idsite }}"
when: "(site_check.json | length) > 0" when: "(site_check.json | length) > 0"
changed_when: false
- name: Add site to Matomo and get ID if not exists - name: Add site to Matomo and get ID if not exists
uri: uri:
@ -42,6 +43,7 @@
set_fact: set_fact:
matomo_site_id: "{{ add_site.json.value }}" matomo_site_id: "{{ add_site.json.value }}"
when: "matomo_site_id is not defined or matomo_site_id is none" when: "matomo_site_id is not defined or matomo_site_id is none"
changed_when: false
- name: Set the Matomo tracking code from a template file - name: Set the Matomo tracking code from a template file
set_fact: set_fact:

View File

@ -2,7 +2,7 @@
include_role: include_role:
name: nginx-https-get-cert name: nginx-https-get-cert
- name: configure nginx redirect configurations - name: "Deploying NGINX redirect configuration for {{ domain }}"
template: template:
src: redirect.domain.nginx.conf.j2 src: redirect.domain.nginx.conf.j2
dest: "{{ nginx.directories.http.servers }}{{ domain }}.conf" dest: "{{ nginx.directories.http.servers }}{{ domain }}.conf"

View File

@ -122,14 +122,20 @@ class TestCspFilters(unittest.TestCase):
# passing a non-decodable object # passing a non-decodable object
self.filter.get_csp_hash(None) self.filter.get_csp_hash(None)
def test_build_csp_header_includes_hashes(self): def test_build_csp_header_includes_hashes_only_if_no_unsafe_inline(self):
"""
script-src has unsafe-inline = False -> hash should be included
style-src has unsafe-inline = True -> hash should NOT be included
"""
header = self.filter.build_csp_header(self.apps, 'app1', self.domains, web_protocol='https') header = self.filter.build_csp_header(self.apps, 'app1', self.domains, web_protocol='https')
# check that the script-src directive includes our inline hash
# script-src includes hash because 'unsafe-inline' is False
script_hash = self.filter.get_csp_hash("console.log('hello');") script_hash = self.filter.get_csp_hash("console.log('hello');")
self.assertIn(script_hash, header) self.assertIn(script_hash, header)
# check that the style-src directive includes its inline hash
# style-src does NOT include hash because 'unsafe-inline' is True
style_hash = self.filter.get_csp_hash("body { background: #fff; }") style_hash = self.filter.get_csp_hash("body { background: #fff; }")
self.assertIn(style_hash, header) self.assertNotIn(style_hash, header)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()