Documentation
¶
Overview ¶
Package httpsec is what every listener and every HTML response of this service shares for the web's own defences: the headers a browser needs to refuse framing and sniffing, the limits on what a client may send, and the timeouts a server holds a connection to.
They live in one place because they are one decision. Two copies of a header list drift: a page served with five of the six is the page the audit finds.
Index ¶
- Constants
- func Apply(w http.ResponseWriter, p Policy)
- func Headers(next http.Handler) http.Handler
- func HeadersWith(next http.Handler, hsts HSTS) http.Handler
- func LimitBody(next http.Handler, limit int64) http.Handler
- func NewServer(addr string, handler http.Handler) *http.Server
- func NoListing(next http.Handler) http.Handler
- func TrustHTTPS(ctx context.Context) context.Context
- type HSTS
- type Policy
Constants ¶
const ( // MaxRequestBody is the most a request body may carry, in bytes. The // largest thing a client legitimately sends is a signing key or a // catalogue in a console call, well under this. MaxRequestBody = 2 << 20 // MaxHeaderBytes is the most a request's header block may carry, // cookies and a bearer included. A bearer carrying every group an // operator holds is several KiB. MaxHeaderBytes = 64 << 10 // ReadHeaderTimeout is how long a client has to send its headers. ReadHeaderTimeout = 10 * time.Second // ReadTimeout is how long a client has to send the whole request, // body included. It is what ends a client that sends one byte a // second. ReadTimeout = 60 * time.Second // WriteTimeout is how long a handler has to answer, counted from the // end of the request headers. It is long because the console runs a // backup, and a restore preview, as one synchronous call that Lambda // stops at 15 minutes (internal/server: backupRunTimeout, 16 // minutes): a shorter deadline would cut the answer to a backup that // is still running. It still ends a client that does not read. WriteTimeout = 20 * time.Minute // IdleTimeout is how long a kept-alive connection may sit unused. IdleTimeout = 2 * time.Minute )
Limits on a listener. They are deliberately generous for what the service really receives -- a token request is a few KiB, a console call a few more -- and small beside what net/http would otherwise read for anybody who asks: the standard library reads a header block of 1 MiB and a body of any size, with no deadline on either.
const DefaultHSTSMaxAge = 365 * 24 * time.Hour
DefaultHSTSMaxAge is how long a browser is told to keep using https for a host: a year, the figure the preload list asks for and the longest anybody has reason to ask.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
func Apply(w http.ResponseWriter, p Policy)
Apply sets the four headers for one response under p. A handler whose page needs a different policy calls it again: the last write wins.
func Headers ¶
Headers sets the default policy on every response, so that no page is served without it by having been forgotten. A handler that needs another policy sets it with Apply. It says nothing about HSTS: see HeadersWith.
func HeadersWith ¶ added in v1.77.1
HeadersWith is Headers that also sends Strict-Transport-Security under hsts to a request that arrived over https. A header already on the response when the request reaches this middleware is left as it is.
func LimitBody ¶
LimitBody refuses a request whose body is larger than limit, and stops reading one that turns out larger than it said.
A declared length over the limit is refused at once with 413, before a handler runs; a body of unknown length (chunked) or one that lies about its length is cut off by http.MaxBytesHandler, and the handler that reads it sees the error.
func NewServer ¶
NewServer is an http.Server holding the limits above.
func NoListing ¶
NoListing answers a request for a directory with 404 instead of the file server's listing of what is in it.
func TrustHTTPS ¶ added in v1.77.1
TrustHTTPS marks a request as having reached the service over https, for a front the service itself trusts to say so: the Lambda adapter, whose payload comes from API Gateway and from nowhere else. Only code in this process can set it; nothing a client sends does.
Types ¶
type HSTS ¶ added in v1.77.1
type HSTS struct {
// MaxAge is how long a browser keeps the rule, in whole seconds. Zero
// sends no header.
MaxAge time.Duration
// IncludeSubDomains extends the rule to every subdomain of the host.
IncludeSubDomains bool
// PublicURL is the address the service is published at. When it is
// https, a request whose Host is that host is taken to have arrived over
// https at a front that ends TLS, unless the front says it did not
// ([HSTS.secure]). Empty or http leaves only a TLS connection and
// [TrustHTTPS] to say so.
PublicURL string
}
HSTS is what a service says about Strict-Transport-Security. The zero value says nothing.
The header is sent on a response only when the request arrived over https as this service sees it ([HSTS.secure]) -- a header on a plain-http response is ignored by browsers (RFC 6797 section 8.1) and a server is told not to send it (section 7.2). It never carries `preload`: that is a commitment about every subdomain of a registrable domain, made once by the owner of the domain, not by one service on it.
type Policy ¶
type Policy struct {
// ScriptNonce lets the page's one inline script run. Empty is no script
// at all beyond this origin's own files.
ScriptNonce string
// FormsMayRedirect leaves out `form-action`. A page whose form ends a
// sign-in is answered with a redirect to the application, and a browser
// that enforces `form-action` checks the redirect's target too: with
// `'self'` it would stop the person on a blank page at the very end of
// signing in. These pages are the issuer's recovery form and its agent
// consent page.
FormsMayRedirect bool
}
Policy is the Content-Security-Policy of one page.
func (Policy) String ¶
String is the header's value.
`style-src` allows inline styles because the service's own pages carry one `<style>` block, and the console's component library writes style rules at run time; scripts are this origin's files, and nothing inline except by nonce. `img-src` allows `data:` for the few inline images.