diff --git a/lib/app.js b/lib/app.js
index 20968ef..211410c 100644
--- a/lib/app.js
+++ b/lib/app.js
@@ -8,6 +8,7 @@ const handlebars = require("handlebars");
const httpGracefulShutdown = require("http-graceful-shutdown");
const routes = require("./routes.js");
+const csp = require("./server-infra/csp.js");
const errorHandler = require("./server-infra/error-handler.js");
const handlebarsSectionHelper = require("./server-infra/handlebars-section-helper.js");
const headers = require("./server-infra/headers.js");
@@ -29,6 +30,7 @@ app
section: handlebarsSectionHelper
}
}))
+ .use(csp)
.use(errorHandler)
.use(headers)
.use(router.routes())
diff --git a/lib/server-infra/csp.js b/lib/server-infra/csp.js
new file mode 100644
index 0000000..50a3b4e
--- /dev/null
+++ b/lib/server-infra/csp.js
@@ -0,0 +1,11 @@
+"use strict";
+const { randomUUID } = require("crypto");
+
+module.exports = async (ctx, next) => {
+ const nonce = randomUUID();
+ ctx.state.cspNonce = nonce;
+
+ ctx.set("Content-Security-Policy", `object-src 'none'; script-src 'nonce-${nonce}'; base-uri 'none';`);
+
+ await next();
+};
diff --git a/views/agreement-status.hbs b/views/agreement-status.hbs
index f30742c..8f78c7a 100644
--- a/views/agreement-status.hbs
+++ b/views/agreement-status.hbs
@@ -98,7 +98,7 @@ label.disabled-control {
-