nuxt-security
Version:
🛡️ Security Module for Nuxt based on HTTP Headers and Middleware
41 lines (40 loc) • 1.53 kB
JavaScript
import { defineNitroPlugin } from "nitropack/runtime";
import sriHashes from "#sri-hashes";
import { resolveSecurityRules } from "../context/index.js";
const SCRIPT_RE = /<script((?=[^>]+\bsrc="([^"]+)")(?![^>]+\bintegrity="[^"]+")[^>]+)(?:\/>|><\/script>)/g;
const LINK_RE = /<link((?=[^>]+\brel="(?:stylesheet|preload|modulepreload)")(?=[^>]+\bhref="([^"]+)")(?![^>]+\bintegrity="[\w\-+/=]+")[^>]+)>/g;
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook("render:html", (html, { event }) => {
const rules = resolveSecurityRules(event);
if (!rules.enabled || !rules.sri) {
return;
}
const sections = ["body", "bodyAppend", "bodyPrepend", "head"];
for (const section of sections) {
html[section] = html[section].map((element) => {
if (typeof element !== "string") {
return element;
}
element = element.replace(SCRIPT_RE, (match, rest, src) => {
const hash = sriHashes[src];
if (hash) {
const integrityScript = `<script integrity="${hash}"${rest}><\/script>`;
return integrityScript;
} else {
return match;
}
});
element = element.replace(LINK_RE, (match, rest, href) => {
const hash = sriHashes[href];
if (hash) {
const integrityLink = `<link integrity="${hash}"${rest}>`;
return integrityLink;
} else {
return match;
}
});
return element;
});
}
});
});