The template's files at a77fd30, without its history or LICENSE, after script/rename simplexcalc. Model: opus-5-5
68 lines
2.3 KiB
Go
68 lines
2.3 KiB
Go
package middleware
|
|
|
|
import "net/http"
|
|
|
|
// Security response headers.
|
|
const (
|
|
// hstsValue is served even where TLS terminates at a reverse
|
|
// proxy, so the browser enforces HTTPS end to end. Off when
|
|
// config.HSTS is false (development), because pinning a
|
|
// developer's browser to HTTPS on localhost is a self-inflicted
|
|
// outage that outlives the process.
|
|
hstsValue = "max-age=31536000; includeSubDomains"
|
|
|
|
// cspValue is the baseline. Every template ships with external CSS
|
|
// and no inline script, style or event handler, so nothing needs
|
|
// 'unsafe-inline' and nothing should be given it: the moment a
|
|
// project seeded from this template adds 'unsafe-inline', the
|
|
// policy stops being a defence against injected script and becomes
|
|
// decoration.
|
|
cspValue = "default-src 'self'; " +
|
|
"base-uri 'self'; " +
|
|
"form-action 'self'; " +
|
|
"frame-ancestors 'none'; " +
|
|
"object-src 'none'"
|
|
|
|
// permissionsPolicyValue denies the browser features this
|
|
// application does not use.
|
|
permissionsPolicyValue = "accelerometer=(), autoplay=(), camera=(), " +
|
|
"display-capture=(), encrypted-media=(), geolocation=(), " +
|
|
"gyroscope=(), magnetometer=(), microphone=(), midi=(), " +
|
|
"payment=(), picture-in-picture=(), " +
|
|
"publickey-credentials-get=(), screen-wake-lock=(), usb=(), " +
|
|
"xr-spatial-tracking=()"
|
|
|
|
referrerPolicyValue = "strict-origin-when-cross-origin"
|
|
frameOptionsValue = "DENY"
|
|
contentTypeOptsVal = "nosniff"
|
|
)
|
|
|
|
// SecurityHeaders sets the response security headers before the handler
|
|
// runs, so they are on every response the router produces — 404s,
|
|
// handler error bodies, static assets, and the bare 500 the panic
|
|
// recoverer writes.
|
|
//
|
|
// X-Frame-Options duplicates the CSP frame-ancestors directive on
|
|
// purpose, for browsers that do not implement the latter.
|
|
func (m *Middleware) SecurityHeaders() func(http.Handler) http.Handler {
|
|
hsts := m.cfg.HSTS
|
|
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
h := w.Header()
|
|
|
|
if hsts {
|
|
h.Set("Strict-Transport-Security", hstsValue)
|
|
}
|
|
|
|
h.Set("Content-Security-Policy", cspValue)
|
|
h.Set("X-Frame-Options", frameOptionsValue)
|
|
h.Set("X-Content-Type-Options", contentTypeOptsVal)
|
|
h.Set("Referrer-Policy", referrerPolicyValue)
|
|
h.Set("Permissions-Policy", permissionsPolicyValue)
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|