diff --git a/max/app.py b/max/app.py index f59464e..bebbd2f 100644 --- a/max/app.py +++ b/max/app.py @@ -16,6 +16,7 @@ from .middlewares import ( add_middleware_stack, ) from .routes import init_routes +from .security_headers import init_security_headers from .sessions import SessionInterface from .translations import TranslationHandler @@ -64,6 +65,7 @@ def main(): register_cli(app) init_auth(app) init_routes(app) + init_security_headers(app) return app diff --git a/max/security_headers.py b/max/security_headers.py new file mode 100644 index 0000000..8f76f8f --- /dev/null +++ b/max/security_headers.py @@ -0,0 +1,29 @@ +CONTENT_SECURITY_POLICY = "; ".join( + ( + "default-src 'none'", + "style-src 'self'", + "img-src 'self'", + "font-src 'self'", + "form-action 'self'", + "frame-ancestors 'none'", + "base-uri 'none'", + ) +) +HSTS_MAX_AGE = 7 * 24 * 60 * 60 # in seconds + + +def init_security_headers(app): + headers = { + "Content-Security-Policy": CONTENT_SECURITY_POLICY, + "X-Frame-Options": "DENY", + "X-Content-Type-Options": "nosniff", + "Referrer-Policy": "same-origin", + } + if not app.debug: + headers["Strict-Transport-Security"] = f"max-age={HSTS_MAX_AGE}" + + # after_request also covers static files, 404 and error responses + @app.after_request + def set_security_headers(response): + response.headers.update(headers) + return response