This is an automated email from the ASF dual-hosted git repository.
gcruz pushed a commit to branch gc/8470
in repository https://gitbox.apache.org/repos/asf/allura.git
The following commit(s) were added to refs/heads/gc/8470 by this push:
new c88f37efc fixup! fixup! fixup! fixup! [#8470] added default csp
headers and configurable options to add additional frame-src and form-action
c88f37efc is described below
commit c88f37efc45368fdc49f4c8d9e3803710c213bb8
Author: Guillermo Cruz <[email protected]>
AuthorDate: Thu Oct 6 11:18:44 2022 -0600
fixup! fixup! fixup! fixup! [#8470] added default csp headers and
configurable options to add additional frame-src and form-action
---
Allura/allura/lib/app_globals.py | 18 +++++-------------
Allura/allura/lib/custom_middleware.py | 11 +++++++----
Allura/allura/tests/functional/test_root.py | 17 +++++++++++------
Allura/development.ini | 6 ++++--
4 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 2f3ccc8fc..d657423e5 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -668,24 +668,16 @@ class Globals:
return asbool(config['csp.report_mode'])
return False
- @property
- def csp_frame_sources(self):
- if config.get('csp.frame_sources'):
- return aslist(config['csp.frame_sources'], sep=',')
- return None
-
- @property
- def csp_form_action_urls(self):
- if config.get('csp.form_action_urls'):
- return aslist(config['csp.form_action_urls'], sep=',')
- return None
-
@property
def csp_report_uri(self):
if config.get('csp.report_uri'):
return config['csp.report_uri']
return None
-
+ @property
+ def csp_report_uri_enforce(self):
+ if config.get('csp.report_uri_enforce'):
+ return config['csp.report_uri_enforce']
+ return None
class Icon:
def __init__(self, css, title=None):
diff --git a/Allura/allura/lib/custom_middleware.py
b/Allura/allura/lib/custom_middleware.py
index 7a02ef7e0..cd8267836 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -470,15 +470,18 @@ class ContentSecurityPolicyMiddleware:
resp = req.get_response(self.app)
report_uri = ''
report_suffix = ''
+ report_uri_enforce = ''
if self.config['base_url'].startswith('https'):
resp.headers.add('Content-Security-Policy',
'upgrade-insecure-requests')
if g.csp_report_mode and g.csp_report_uri:
report_suffix = '-Report-Only'
report_uri = f'; report-uri {g.csp_report_uri}; report-to
{g.csp_report_uri}'
- if g.csp_frame_sources:
- resp.headers.add(f'Content-Security-Policy{report_suffix}',
f"frame-src 'self' {' '.join(g.csp_frame_sources)}{report_uri}")
- if g.csp_form_action_urls:
- resp.headers.add(f'Content-Security-Policy{report_suffix}',
f"form-action {' '.join(g.csp_form_action_urls)}{report_uri}")
+ if g.csp_report_uri_enforce:
+ report_uri_enforce = f'; report-uri {g.csp_report_uri_enforce};
report-to {g.csp_report_uri_enforce:}'
+ if self.config.get('csp.frame_sources'):
+ resp.headers.add(f'Content-Security-Policy{report_suffix}',
f"frame-src {self.config['csp.frame_sources']}{report_uri}{report_uri_enforce}")
+ if self.config.get('csp.form_action_urls'):
+ resp.headers.add(f'Content-Security-Policy{report_suffix}',
f"form-action
{self.config['csp.form_action_urls']}{report_uri}{report_uri_enforce}")
resp.headers.add('Content-Security-Policy', "object-src 'none'")
resp.headers.add('Content-Security-Policy', "frame-ancestors 'self'")
return resp(environ, start_response)
diff --git a/Allura/allura/tests/functional/test_root.py
b/Allura/allura/tests/functional/test_root.py
index 92406ed8a..cb610651e 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -190,21 +190,26 @@ class TestRootController(TestController):
def test_headers(self):
resp = self.app.get('/p')
- assert resp.headers.getall('Content-Security-Policy') == ["form-action
'self'", "object-src 'none'",
+ assert resp.headers.getall('Content-Security-Policy') == ["frame-src
'self' www.youtube-nocookie.com",
+ "form-action
'self'",
+ "object-src
'none'",
"frame-ancestors 'self'"]
- @mock.patch.dict(tg.config, {'csp.frame_sources':
'www.youtube-nocookie.com'})
def test_headers_config(self):
resp = self.app.get('/p')
assert "frame-src 'self' www.youtube-nocookie.com" in
resp.headers.getall('Content-Security-Policy')
- @mock.patch.dict(tg.config, {'csp.report_mode': True, 'csp.report_uri':
'https://example.com/r/d/csp/reportOnly',
- 'csp.frame_sources':
'www.youtube-nocookie.com'})
+ @mock.patch.dict(tg.config, {'csp.report_mode': True, 'csp.report_uri':
'https://example.com/r/d/csp/reportOnly'})
def test_headers_report(self):
resp = self.app.get('/p/wiki/Home/')
assert resp.headers.getall('Content-Security-Policy-Report-Only') == [
- "frame-src 'self' www.youtube-nocookie.com; report-uri
https://example.com/r/d/csp/reportOnly",
- "form-action 'self'; report-uri
https://example.com/r/d/csp/reportOnly"]
+ "frame-src 'self' www.youtube-nocookie.com; report-uri
https://example.com/r/d/csp/reportOnly; report-to
https://example.com/r/d/csp/reportOnly",
+ "form-action 'self'; report-uri
https://example.com/r/d/csp/reportOnly; report-to
https://example.com/r/d/csp/reportOnly"]
+
+ @mock.patch.dict(tg.config, {'csp.report_uri_enforce':
'https://example.com/r/d/csp/enforce'})
+ def test_headers_report_enforce(self):
+ resp = self.app.get('/p/wiki/Home/')
+ assert "frame-src 'self' www.youtube-nocookie.com; report-uri
https://example.com/r/d/csp/enforce; report-to
https://example.com/r/d/csp/enforce" in
resp.headers.getall('Content-Security-Policy')
class TestRootWithSSLPattern(TestController):
diff --git a/Allura/development.ini b/Allura/development.ini
index 858a3d3be..03207ed1e 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -661,10 +661,12 @@ userstats.count_lines_of_code = true
; CSP Headers
; enable report mode
; csp.report_mode = false
-; csp.report_uri =
+; csp.report_uri = https://example.com/r/d/csp/reportOnly
+; csp.report_uri_enforce = https://example.com/r/d/csp/enforce
+
; frame-src list of valid sources for loading frames
-; csp.frame_sources =
+csp.frame_sources = 'self' www.youtube-nocookie.com
; form-action valid sources that can be used as an HTML <form> action
csp.form_action_urls = 'self'