Fix content security policy for the CDN

The CDN URLs aren’t in included in the content security policy. So
browsers will refuse to load them.

This commit:
- adds each of the CDN URLs to the
- only prepend URLs in CSS files with `/static/` if we’re running
  locally (because the CDN URLs are like `static.example.com` not
  `example.com/static`)
This commit is contained in:
Chris Hill-Scott
2018-11-29 11:29:52 +00:00
parent 74459b2f2a
commit fe6610c221
4 changed files with 31 additions and 14 deletions

View File

@@ -496,17 +496,24 @@ def save_service_or_org_after_request(response):
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
def useful_headers_after_request(response):
notify_environment = os.environ['NOTIFY_ENVIRONMENT']
response.headers.add('X-Frame-Options', 'deny')
response.headers.add('X-Content-Type-Options', 'nosniff')
response.headers.add('X-XSS-Protection', '1; mode=block')
response.headers.add('Content-Security-Policy', (
"default-src 'self' 'unsafe-inline';"
"script-src 'self' *.google-analytics.com 'unsafe-inline' 'unsafe-eval' data:;"
"default-src 'self' {} 'unsafe-inline';"
"script-src 'self' {} *.google-analytics.com 'unsafe-inline' 'unsafe-eval' data:;"
"connect-src 'self' *.google-analytics.com;"
"object-src 'self';"
"font-src 'self' data:;"
"img-src 'self' *.google-analytics.com *.notifications.service.gov.uk {} data:;"
"frame-src 'self' www.youtube.com;".format(get_cdn_domain())
"font-src 'self' {} data:;"
"img-src 'self' {} *.google-analytics.com *.notifications.service.gov.uk {} data:;"
"frame-src 'self' www.youtube.com;".format(
configs[notify_environment].ASSET_DOMAIN,
configs[notify_environment].ASSET_DOMAIN,
configs[notify_environment].ASSET_DOMAIN,
configs[notify_environment].ASSET_DOMAIN,
get_cdn_domain(),
)
))
if 'Cache-Control' in response.headers:
del response.headers['Cache-Control']

View File

@@ -74,6 +74,7 @@ class Config(object):
REDIS_URL = os.environ.get('REDIS_URL')
REDIS_ENABLED = os.environ.get('REDIS_ENABLED') == '1'
ASSET_DOMAIN = ''
ASSET_PATH = '/static/'
@@ -94,6 +95,8 @@ class Development(Config):
ANTIVIRUS_API_HOST = 'http://localhost:6016'
ANTIVIRUS_API_KEY = 'test-key'
ASSET_PATH = '/static/'
class Test(Development):
DEBUG = True
@@ -109,6 +112,8 @@ class Test(Development):
ANTIVIRUS_API_HOST = 'https://test-antivirus'
ANTIVIRUS_API_KEY = 'test-antivirus-secret'
ASSET_DOMAIN = 'static.example.com'
class Preview(Config):
HTTP_PROTOCOL = 'https'
@@ -119,6 +124,7 @@ class Preview(Config):
MOU_BUCKET_NAME = 'notify.works-mou'
NOTIFY_ENVIRONMENT = 'preview'
CHECK_PROXY_HEADER = False
ASSET_DOMAIN = 'static.notify.works'
ASSET_PATH = 'https://static.notify.works/'
@@ -132,6 +138,7 @@ class Staging(Config):
MOU_BUCKET_NAME = 'staging-notify.works-mou'
NOTIFY_ENVIRONMENT = 'staging'
CHECK_PROXY_HEADER = False
ASSET_DOMAIN = 'static.staging-notify.works'
ASSET_PATH = 'https://static.staging-notify.works/'
@@ -145,6 +152,7 @@ class Live(Config):
MOU_BUCKET_NAME = 'notifications.service.gov.uk-mou'
NOTIFY_ENVIRONMENT = 'live'
CHECK_PROXY_HEADER = False
ASSET_DOMAIN = 'static.notifications.service.gov.uk'
ASSET_PATH = 'https://static.notifications.service.gov.uk/'

View File

@@ -37,7 +37,7 @@ gulp.task('copy:govuk_template:css', () => gulp.src(paths.template + 'assets/sty
}))
.on('error', plugins.sass.logError)
.pipe(plugins.cssUrlAdjuster({
prependRelative: '/static/',
prependRelative: process.env.NOTIFY_ADMIN_ENVIRONMENT == 'config.Development' ? '/static/' : '/',
}))
.pipe(gulp.dest(paths.dist + 'stylesheets/'))
);

View File

@@ -8,12 +8,13 @@ def test_owasp_useful_headers_set(client, mocker):
assert response.headers['X-Content-Type-Options'] == 'nosniff'
assert response.headers['X-XSS-Protection'] == '1; mode=block'
assert response.headers['Content-Security-Policy'] == (
"default-src 'self' 'unsafe-inline';"
"script-src 'self' *.google-analytics.com 'unsafe-inline' 'unsafe-eval' data:;"
"default-src 'self' static.example.com 'unsafe-inline';"
"script-src 'self' static.example.com *.google-analytics.com 'unsafe-inline' 'unsafe-eval' data:;"
"connect-src 'self' *.google-analytics.com;"
"object-src 'self';"
"font-src 'self' data:;"
"img-src 'self' *.google-analytics.com *.notifications.service.gov.uk static-logos.test.com data:;"
"font-src 'self' static.example.com data:;"
"img-src "
"'self' static.example.com *.google-analytics.com *.notifications.service.gov.uk static-logos.test.com data:;"
"frame-src 'self' www.youtube.com;"
)
@@ -25,11 +26,12 @@ def test_headers_non_ascii_characters_are_replaced(client, mocker):
assert response.status_code == 200
assert response.headers['Content-Security-Policy'] == (
"default-src 'self' 'unsafe-inline';"
"script-src 'self' *.google-analytics.com 'unsafe-inline' 'unsafe-eval' data:;"
"default-src 'self' static.example.com 'unsafe-inline';"
"script-src 'self' static.example.com *.google-analytics.com 'unsafe-inline' 'unsafe-eval' data:;"
"connect-src 'self' *.google-analytics.com;"
"object-src 'self';"
"font-src 'self' data:;"
"img-src 'self' *.google-analytics.com *.notifications.service.gov.uk static-logos??.test.com data:;"
"font-src 'self' static.example.com data:;"
"img-src "
"'self' static.example.com *.google-analytics.com *.notifications.service.gov.uk static-logos??.test.com data:;"
"frame-src 'self' www.youtube.com;"
)