Documentation
¶
Overview ¶
Package httpsec is the security-header middleware for moth's HTML and JSON surfaces: a strict Content-Security-Policy, HSTS (https only), X-Content-Type-Options, Referrer-Policy and frame options.
CSP and unsafe-inline. The two families of pages moth serves are covered by two default policies, neither of which uses 'unsafe-inline':
- The admin SPA (DefaultAdminPolicy) is a Vite production build: its only script and stylesheet are external files loaded with src=/href=, so a plain script-src 'self'; style-src 'self' is sufficient — no inline code, no nonce, no hash.
- The hosted pages (DefaultHostedPolicy) — verify / reset / confirm-email — render one inline <style> block carrying the project's theme CSS. Rather than weaken the policy with 'unsafe-inline', the middleware mints a fresh base64 nonce per request, substitutes it for the "%NONCE%" token in the policy, and exposes it via NonceFromContext so the template can stamp nonce="…" onto that <style> element. script-src is 'none' because the hosted pages ship no JavaScript at all.
A per-request nonce (not a static hash) is used for the hosted pages because the inline CSS is dynamic — it embeds each project's theme tokens — so its hash is not stable across projects or theme edits.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NonceFromContext ¶
NonceFromContext returns the CSP nonce assigned to the current request, or "" when the active policy does not use a nonce. Templates read it to stamp nonce="…" onto their inline <style>/<script> elements.
Types ¶
type Policy ¶
type Policy struct {
// ContentSecurityPolicy is the Content-Security-Policy header value. When
// it contains the token %NONCE%, each request gets a fresh nonce
// substituted in and made available through NonceFromContext.
ContentSecurityPolicy string
// HSTS enables Strict-Transport-Security. It is only emitted on requests
// served over https (or forwarded as https), never plain http, so a
// misconfiguration cannot lock clients out of an http instance.
HSTS bool
// HSTSMaxAge is the max-age of the HSTS header; defaults to 365 days when
// zero and HSTS is enabled.
HSTSMaxAge time.Duration
// HSTSIncludeSubdomains adds includeSubDomains to the HSTS header.
HSTSIncludeSubdomains bool
// FrameOptions sets X-Frame-Options (e.g. "DENY", "SAMEORIGIN"); empty
// omits the header (rely on CSP frame-ancestors instead).
FrameOptions string
// ReferrerPolicy sets Referrer-Policy; empty omits the header.
ReferrerPolicy string
// ContentTypeOptions emits X-Content-Type-Options: nosniff when true.
ContentTypeOptions bool
}
Policy is the set of security headers to emit. Construct one of the defaults and adjust as needed, or build your own.
func DefaultAdminPolicy ¶
func DefaultAdminPolicy() Policy
DefaultAdminPolicy returns the strict policy for the admin SPA and JSON APIs: no inline code, no nonce. HSTS is left to the caller to enable when the instance is served over https.
func DefaultHostedPolicy ¶
func DefaultHostedPolicy() Policy
DefaultHostedPolicy returns the policy for the server-rendered hosted pages. It permits the single inline <style> block via a per-request nonce and forbids scripts entirely.