On this page
csp
The csp() middleware can be used to add
Content-Security-Policy headers
to HTTP requests. These restrict which resources a document is allowed to load.
import { csp } from "fresh";
const app = new App()
.use(csp({
// If true, sets Content-Security-Policy-Report-Only header instead
// of Content-Security-Policy
reportOnly: true,
// If set, adds Reporting-Endpoints, report-to, and report-uri
// directive.
reportTo: "/api/csp-reports",
// Additional CSP directives to add or override the defaults
csp: [
"script-src 'self' 'unsafe-inline' 'https://example.com'",
],
}))
.get("/", () => new Response("hello"));Nonce-based CSP
For stricter security, you can use nonce-based CSP instead of 'unsafe-inline'.
This ensures only inline <script> and <style> tags rendered by Fresh are
allowed to execute.
import { csp } from "fresh";
const app = new App()
.use(csp({ useNonce: true }))
.get("/", (ctx) => {
return ctx.render(
<html>
<head>
<style>{"body { color: red; }"}</style>
</head>
<body>
<h1>Hello</h1>
</body>
</html>,
);
});When useNonce is enabled:
- Fresh automatically injects a unique
nonceattribute onto every inline<script>and<style>tag during server rendering. - The CSP header replaces
'unsafe-inline'with'nonce-{value}'inscript-src,style-src,default-src,script-src-elem,style-src-elem, andstyle-src-attrdirectives. - Each request gets a fresh nonce, so the value cannot be predicted by an attacker.
- Non-rendered responses (e.g. API routes returning JSON) fall back to
'unsafe-inline'since there is no rendering step to generate a nonce.
WarningIf you set an explicit
nonceattribute on a tag, it will be preserved in the HTML, but the CSP header will only contain the Fresh-generated nonce. The browser will block the tag unless its nonce matches the one in the CSP header. To avoid this, let Fresh manage nonces automatically.
Options
See the API docs for a list of all supported options.