From 5da374bbc94df0c7ef4e8829d1b6824cf8917dcf Mon Sep 17 00:00:00 2001 From: George Drummond Date: Wed, 12 Dec 2018 13:36:29 -0500 Subject: [PATCH 1/4] Suggestions from http://flask.pocoo.org/docs/1.0/security/ --- atst/app.py | 15 +++++++++++++++ templates/components/alert.html | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/atst/app.py b/atst/app.py index 88002c4f..7cc3574d 100644 --- a/atst/app.py +++ b/atst/app.py @@ -71,6 +71,7 @@ def make_app(config): app.form_cache = FormCache(app.redis) apply_authentication(app) + set_default_headers(app) return app @@ -91,6 +92,20 @@ def make_flask_callbacks(app): return response +def set_default_headers(app): + @app.after_request + def _set_security_headers(response): + response.headers[ + "Strict-Transport-Security" + ] = "max-age=31536000; includeSubDomains" + response.headers["Content-Security-Policy"] = "default-src 'self'" + response.headers["X-Content-Type-Options"] = "nosniff" + response.headers["X-Frame-Options"] = "SAMEORIGIN" + response.headers["X-XSS-Protection"] = "1; mode=block" + + return response + + def map_config(config): return { **config["default"], diff --git a/templates/components/alert.html b/templates/components/alert.html index d170e2bb..b510457e 100644 --- a/templates/components/alert.html +++ b/templates/components/alert.html @@ -54,7 +54,7 @@ {% elif actions is iterable %} {% for action in actions %} - + {% if 'icon' in action %}{{ Icon(action["icon"]) }}{% endif %} {{ action["label"] }} From ec09c27a38f685e4023cc3a1c4178bab9700557a Mon Sep 17 00:00:00 2001 From: George Drummond Date: Thu, 13 Dec 2018 13:54:19 -0500 Subject: [PATCH 2/4] On fix unsafe-eval header and websockets on development --- atst/app.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/atst/app.py b/atst/app.py index 7cc3574d..5d79d9b5 100644 --- a/atst/app.py +++ b/atst/app.py @@ -98,11 +98,15 @@ def set_default_headers(app): response.headers[ "Strict-Transport-Security" ] = "max-age=31536000; includeSubDomains" - response.headers["Content-Security-Policy"] = "default-src 'self'" response.headers["X-Content-Type-Options"] = "nosniff" response.headers["X-Frame-Options"] = "SAMEORIGIN" response.headers["X-XSS-Protection"] = "1; mode=block" + if ENV == 'dev': + response.headers["Content-Security-Policy"] = "default-src 'self' 'unsafe-eval'; connect-src *" + else: + response.headers["Content-Security-Policy"] = "default-src 'self' 'unsafe-eval'" + return response From 3bff2fcb231c90777aa5fe691dcb46135c9e80f5 Mon Sep 17 00:00:00 2001 From: George Drummond Date: Thu, 13 Dec 2018 13:59:54 -0500 Subject: [PATCH 3/4] Format code --- atst/app.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/atst/app.py b/atst/app.py index 5d79d9b5..428f77f5 100644 --- a/atst/app.py +++ b/atst/app.py @@ -102,10 +102,14 @@ def set_default_headers(app): response.headers["X-Frame-Options"] = "SAMEORIGIN" response.headers["X-XSS-Protection"] = "1; mode=block" - if ENV == 'dev': - response.headers["Content-Security-Policy"] = "default-src 'self' 'unsafe-eval'; connect-src *" + if ENV == "dev": + response.headers[ + "Content-Security-Policy" + ] = "default-src 'self' 'unsafe-eval'; connect-src *" else: - response.headers["Content-Security-Policy"] = "default-src 'self' 'unsafe-eval'" + response.headers[ + "Content-Security-Policy" + ] = "default-src 'self' 'unsafe-eval'" return response From 15a32a1dc5c405383e7f4dc31f9d307681b637a3 Mon Sep 17 00:00:00 2001 From: George Drummond Date: Mon, 17 Dec 2018 11:42:27 -0500 Subject: [PATCH 4/4] Exclude set_default_headers from coverage report --- atst/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/app.py b/atst/app.py index 428f77f5..84348e68 100644 --- a/atst/app.py +++ b/atst/app.py @@ -92,7 +92,7 @@ def make_flask_callbacks(app): return response -def set_default_headers(app): +def set_default_headers(app): # pragma: no cover @app.after_request def _set_security_headers(response): response.headers[