Documentation
¶
Overview ¶
Package secure holds the transport-neutral implementations of the two web-security defenses nexus applies — security response headers and CSRF — with no dependency beyond httpx and the standard library.
It exists so BOTH the framework core (Config.Middleware.Security, read in package nexus) and the extension/security plugin can share one copy of the logic. The core can't import extension/security (that package imports nexus, which would cycle), so the reusable pieces live down here where everything can reach them.
Most apps never import this package directly: they either set [runtime.middleware.security] in nexus.toml (core path) or load extension/security for the dashboard tab + per-route bundles. The exported surface here is what those two callers wrap.
Index ¶
- Constants
- func ApplyCSRFDefaults(c *CSRFConfig)
- func ApplyHeaderDefaults(h *HeadersConfig)
- func BuildHSTS(h *HSTSConfig) string
- func CSRFHandler(cfg *CSRFConfig) httpx.HandlerFunc
- func DefaultSkip(c *httpx.Ctx) bool
- func GenerateToken(n int) string
- func HeadersHandler(h *HeadersConfig) httpx.HandlerFunc
- func ValidateCSRF(c *CSRFConfig) error
- type CSRFConfig
- type HSTSConfig
- type HeadersConfig
Constants ¶
const ( // Omit marks a header the operator explicitly turned off. An empty // string means "apply the default"; Omit ("-") means "send nothing". Omit = "-" DefaultFrameOptions = "DENY" DefaultReferrerPolicy = "strict-origin-when-cross-origin" DefaultHSTSMaxAge = 31536000 // one year, in seconds DefaultCSRFCookie = "csrftoken" // matches client.DefaultCSRFCookie DefaultCSRFHeader = "X-CSRFToken" // matches client.DefaultCSRFHeader DefaultCSRFField = "csrf_token" // form-body fallback field DefaultTokenBytes = 32 // 256-bit token DefaultCSRFMaxAge = 12 * 60 * 60 // 12h cookie lifetime )
Sentinel + default values shared by the header and CSRF logic.
Variables ¶
This section is empty.
Functions ¶
func ApplyCSRFDefaults ¶
func ApplyCSRFDefaults(c *CSRFConfig)
ApplyCSRFDefaults fills the conventional CSRF values.
func ApplyHeaderDefaults ¶
func ApplyHeaderDefaults(h *HeadersConfig)
ApplyHeaderDefaults fills the recommended values so a zero HeadersConfig produces the three safe headers.
func BuildHSTS ¶
func BuildHSTS(h *HSTSConfig) string
BuildHSTS renders the Strict-Transport-Security directive.
func CSRFHandler ¶
func CSRFHandler(cfg *CSRFConfig) httpx.HandlerFunc
CSRFHandler builds the double-submit-cookie CSRF middleware. Call ApplyCSRFDefaults (and ideally ValidateCSRF) on the config first.
- Safe method: ensure the token cookie exists (minting one on first contact) so the SPA has a value to echo, then continue.
- Unsafe method: unless Skip says otherwise, require the request to carry the same token in both the cookie and the header (or form field). A cross-site attacker can drive the victim's browser to send the cookie but can't read it (same-origin policy) to forge the matching header, so a match proves same-origin intent.
func DefaultSkip ¶
DefaultSkip exempts requests that authenticate with an Authorization header. Bearer/API-key auth is not CSRF-vulnerable: a browser never attaches such a header automatically on a cross-site request, so the forgery vector doesn't exist. This lets CSRF be enabled without breaking stateless API clients (curl, mobile, server-to-server).
func GenerateToken ¶
GenerateToken returns a base64url-encoded cryptographically random token. A rand.Read failure is unrecoverable for a security token, so it panics rather than emit a weak value.
func HeadersHandler ¶
func HeadersHandler(h *HeadersConfig) httpx.HandlerFunc
HeadersHandler builds the per-request security-headers middleware. It precomputes every value once (nothing depends on the request) and sets them before the route handler runs, so a handler that writes its own header of the same name still wins. Call ApplyHeaderDefaults on the config first.
func ValidateCSRF ¶
func ValidateCSRF(c *CSRFConfig) error
ValidateCSRF rejects a token size too small to be safe.
Types ¶
type CSRFConfig ¶
type CSRFConfig struct {
CookieName string // default "csrftoken"
HeaderName string // default "X-CSRFToken"
FieldName string // form-body fallback; default "csrf_token"
CookiePath string // default "/"
CookieDomain string // default "" (host-only)
// CookieSecure controls the cookie's Secure flag. nil → auto
// (Secure when the request arrived over https / X-Forwarded-Proto
// https), so dev over http works without a config change.
CookieSecure *bool
// SameSite for the cookie. Zero value → Lax.
SameSite http.SameSite
MaxAge int // cookie lifetime in seconds; default 12h
TokenBytes int // random token size; default 32 (256-bit)
// CheckOrigin adds a defense-in-depth Origin/Referer same-site
// check on top of the token. Off by default: it can misfire behind
// proxies that rewrite Host, and the token alone is sufficient.
CheckOrigin bool
TrustedOrigins []string // extra hosts accepted by the Origin check
// Skip decides per request whether to bypass the check on an unsafe
// method. nil → DefaultSkip (skip requests with an Authorization
// header — bearer/token auth is not CSRF-vulnerable).
Skip func(c *httpx.Ctx) bool
}
CSRFConfig controls the double-submit-cookie check.
type HSTSConfig ¶
type HSTSConfig struct {
MaxAge int // seconds; 0 → DefaultHSTSMaxAge
IncludeSubdomains bool // adds "; includeSubDomains"
Preload bool // adds "; preload"
}
HSTSConfig is the parsed Strict-Transport-Security directive.
type HeadersConfig ¶
type HeadersConfig struct {
// FrameOptions sets X-Frame-Options (clickjacking defense).
// Default "DENY"; "SAMEORIGIN" to allow same-origin framing; "-"
// (Omit) to send nothing (e.g. when you use CSP frame-ancestors).
FrameOptions string
// ContentTypeNosniff sets X-Content-Type-Options: nosniff. nil →
// true (recommended). Point at a false to disable.
ContentTypeNosniff *bool
// ReferrerPolicy sets Referrer-Policy. Default
// "strict-origin-when-cross-origin"; Omit to send nothing.
ReferrerPolicy string
// HSTS, when non-nil, sends Strict-Transport-Security. Opt-in
// because a wrong max-age/preload can lock users out of a domain.
// Browsers ignore it over plain http, so it's safe once on https.
HSTS *HSTSConfig
// ContentSecurityPolicy sets Content-Security-Policy verbatim.
// Empty → not sent (CSP is too app-specific to default).
ContentSecurityPolicy string
// PermissionsPolicy sets Permissions-Policy verbatim. Empty → not
// sent.
PermissionsPolicy string
// CrossOriginOpenerPolicy sets Cross-Origin-Opener-Policy (e.g.
// "same-origin"). Empty → not sent.
CrossOriginOpenerPolicy string
}
HeadersConfig controls the security response headers. Empty string fields take the recommended default; set a field to Omit to drop that header. HSTS, CSP, Permissions-Policy, and COOP are opt-in (nil/empty → not sent) because a wrong value there breaks a site.