55 lines
2.1 KiB
TypeScript
55 lines
2.1 KiB
TypeScript
import { FastifyInstance } from "fastify";
|
|
import fp from "fastify-plugin";
|
|
|
|
async function securityPlugin(app: FastifyInstance) {
|
|
app.addHook("onSend", async (req, reply) => {
|
|
const isEmbed = req.url.startsWith("/api/v1/embed/") || req.url.startsWith("/embed/");
|
|
const isAsset = req.url.startsWith("/assets/") || req.url.startsWith("/favicon") || req.url.startsWith("/icon-") || req.url.endsWith(".js") || req.url.endsWith(".css");
|
|
|
|
if (isEmbed || isAsset) {
|
|
// embed routes need to be frameable by third-party sites
|
|
reply.header("Content-Security-Policy", [
|
|
"default-src 'self'",
|
|
"script-src 'self'",
|
|
"style-src 'self' 'unsafe-inline'",
|
|
"img-src 'self' data:",
|
|
"font-src 'self'",
|
|
"connect-src 'self'",
|
|
"frame-src 'none'",
|
|
"object-src 'none'",
|
|
"frame-ancestors *",
|
|
"base-uri 'self'",
|
|
"form-action 'none'",
|
|
].join("; "));
|
|
reply.header("Cross-Origin-Resource-Policy", "cross-origin");
|
|
reply.header("Access-Control-Allow-Origin", "*");
|
|
reply.header("Access-Control-Allow-Credentials", "false");
|
|
} else {
|
|
reply.header("Content-Security-Policy", [
|
|
"default-src 'self'",
|
|
"script-src 'self'",
|
|
"style-src 'self' 'unsafe-inline'",
|
|
"img-src 'self' data:",
|
|
"font-src 'self'",
|
|
"connect-src 'self'",
|
|
"frame-src 'none'",
|
|
"object-src 'none'",
|
|
"frame-ancestors 'none'",
|
|
"base-uri 'self'",
|
|
"form-action 'self'",
|
|
].join("; "));
|
|
reply.header("X-Frame-Options", "DENY");
|
|
reply.header("Cross-Origin-Opener-Policy", "same-origin");
|
|
reply.header("Cross-Origin-Resource-Policy", "same-origin");
|
|
}
|
|
|
|
reply.header("Referrer-Policy", "no-referrer");
|
|
reply.header("X-Content-Type-Options", "nosniff");
|
|
reply.header("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload");
|
|
reply.header("Permissions-Policy", "camera=(), microphone=(), geolocation=(), interest-cohort=()");
|
|
reply.header("X-DNS-Prefetch-Control", "off");
|
|
});
|
|
}
|
|
|
|
export default fp(securityPlugin, { name: "security" });
|