Browse Source

Fix CSP errors on inline elements in Swagger UI

* Move inline CSS to a separate file
* Inject a CSP nonce using Pyramid tween
merge-requests/169/head
Andrew Shu 2 months ago
committed by talklittle
parent
commit
2718966b2e
  1. 17
      ansible/roles/swagger_ui/files/index.css
  2. 20
      ansible/roles/swagger_ui/files/index.html
  3. 15
      ansible/roles/swagger_ui/tasks/main.yml
  4. 28
      tildes/tildes/tweens.py

17
ansible/roles/swagger_ui/files/index.css

@ -0,0 +1,17 @@
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body {
margin:0;
background: #fafafa;
}

20
tildes/static/swagger-ui-tildes/index.html → ansible/roles/swagger_ui/files/index.html

@ -4,25 +4,7 @@
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="/swagger-ui/swagger-ui.css" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body {
margin:0;
background: #fafafa;
}
</style>
<link rel="stylesheet" type="text/css" href="/swagger-ui/index.css" />
</head>
<body>

15
ansible/roles/swagger_ui/tasks/main.yml

@ -7,3 +7,18 @@
group: "{{ app_username }}"
mode: 0755
remote_src: true
- name: Copy our own custom swagger-ui web assets
block:
- copy:
src: "index.html"
dest: "{{ app_dir }}/static/swagger-ui/index.html"
owner: "{{ app_username }}"
group: "{{ app_username }}"
mode: 0644
- copy:
src: "index.css"
dest: "{{ app_dir }}/static/swagger-ui/index.css"
owner: "{{ app_username }}"
group: "{{ app_username }}"
mode: 0644

28
tildes/tildes/tweens.py

@ -3,6 +3,7 @@
"""Contains Pyramid "tweens", used to insert additional logic into request-handling."""
import secrets
from collections.abc import Callable
from time import time
@ -106,8 +107,35 @@ def theme_cookie_tween_factory(handler: Callable, registry: Registry) -> Callabl
return theme_cookie_tween
def inject_csp_header_tween_factory(handler: Callable, registry: Registry) -> Callable:
# pylint: disable=unused-argument
"""Return a tween function that sets a CSP nonce (for Swagger UI)."""
def inject_csp_header_tween(request: Request) -> Response:
"""Generate a CSP nonce and add it to the request and response.
Only apply to specific routes defined here, to minimize performance overhead.
"""
nonce = None
route_name = request.matched_route.name if request.matched_route else None
if route_name == "pyramid_openapi3.explorer":
nonce = secrets.token_urlsafe(16)
request.csp_nonce = nonce
response = handler(request)
if nonce:
response.headers["Content-Security-Policy"] = (
f"script-src 'self' 'nonce-{nonce}'"
)
return response
return inject_csp_header_tween
def includeme(config: Configurator) -> None:
"""Attach Tildes tweens to the Pyramid config."""
config.add_tween("tildes.tweens.http_method_tween_factory")
config.add_tween("tildes.tweens.metrics_tween_factory")
config.add_tween("tildes.tweens.theme_cookie_tween_factory")
config.add_tween("tildes.tweens.inject_csp_header_tween_factory")
Loading…
Cancel
Save