diff --git a/lib/csp.js b/lib/csp.js new file mode 100644 index 00000000..d37a382f --- /dev/null +++ b/lib/csp.js @@ -0,0 +1,28 @@ +const CSP = { + "default-src": [ + "'self'", + ], + "script-src": [ + "https://code.jquery.com", + "https://cdn.jsdelivr.net", + "https://cdnjs.cloudflare.com", + "https://stackpath.bootstrapcdn.com", + "'unsafe-inline'", + "'unsafe-eval'", + "'self'", + ], + "style-src": [ + "https://cdn.jsdelivr.net", + "https://stackpath.bootstrapcdn.com", + "https://fonts.googleapis.com", + "https://unpkg.com", + "'self'", + ], + "font-src": [ + "https://fonts.gstatic.com", + ], +}; + +module.exports = Object.entries(CSP) + .map(([type, values]) => `${type} ${values.join(" ")}`) + .join("; ") diff --git a/lib/middlewares/express.js b/lib/middlewares/express.js index f021d773..92bc8493 100644 --- a/lib/middlewares/express.js +++ b/lib/middlewares/express.js @@ -1,12 +1,19 @@ const path = require("path"); const express = require("express"); const bodyParser = require("body-parser"); +const csp = require("../csp"); module.exports = (agendash) => { const { api, requeueJobs, deleteJobs, createJob } = agendash; const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); + + app.use((req, res, next) => { + res.header("Content-Security-Policy", csp); + next(); + }); + app.use("/", express.static(path.join(__dirname, "../../public"))); app.get("/api", async (request, response) => { diff --git a/lib/middlewares/fastify.js b/lib/middlewares/fastify.js index e9fb74ee..fdd95fca 100644 --- a/lib/middlewares/fastify.js +++ b/lib/middlewares/fastify.js @@ -1,4 +1,5 @@ const path = require("path"); +const csp = require("../csp"); module.exports = (agendash) => (instance, opts, done) => { const { api, requeueJobs, deleteJobs, createJob } = agendash; @@ -8,6 +9,7 @@ module.exports = (agendash) => (instance, opts, done) => { }); instance.get("/", function (req, reply) { + reply.header("Content-Security-Policy", csp); return reply.sendFile("index.html"); }); diff --git a/lib/middlewares/hapi.js b/lib/middlewares/hapi.js index fe931430..aba3b674 100644 --- a/lib/middlewares/hapi.js +++ b/lib/middlewares/hapi.js @@ -1,11 +1,17 @@ const path = require("path"); const pack = require("../../package.json"); +const csp = require("../csp"); module.exports = (agendash) => { const { api, requeueJobs, deleteJobs, createJob } = agendash; return { pkg: pack, register: (server, options) => { + server.ext("onPreResponse", (req, h) => { + req.response.header("Content-Security-Policy", csp); + return h.continue; + }); + server.route([ { method: "GET", diff --git a/lib/middlewares/koa.js b/lib/middlewares/koa.js index 13efa9bc..4737bb4d 100644 --- a/lib/middlewares/koa.js +++ b/lib/middlewares/koa.js @@ -2,10 +2,16 @@ const path = require("path"); const bodyParser = require("koa-bodyparser"); const Router = require("koa-router"); const koaStatic = require("koa-static"); +const csp = require("../csp"); module.exports = (agendash) => { const middlewares = []; + middlewares.push(async (ctx, next) => { + await next(); + ctx.set("Content-Security-Policy", csp); + }); + middlewares.push( koaStatic(path.resolve(__dirname, "../../public"), { defer: true }) );