safehttp

package
v0.0.0-...-f115076 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2024 License: Apache-2.0 Imports: 21 Imported by: 15

Documentation

Overview

Package safehttp provides a framework for building secure-by-default web applications. See https://github.com/google/go-safeweb#readme to learn about the goals and features.

Safe Responses

HTTP responses need to be crafted carefully in order to prevent common web vulnerabilities like Cross-site Scripting (XSS). To help with this, we use Safe Responses.

Safe Responses are HTTP responses which have been determined to be safe when received by a modern, popular web browser. For example, we consider HTML responses generated using a template system enforcing contextual autoescaping to be safe, e.g. modern Angular or github.com/google/safehtml/template. Read more about contextual autoescaping here: https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/42934.pdf.

The Go Safe Web ResponseWriter implementation only accepts Safe Responses instead of byte slices.

Since different projects will consider different ways of crafting a response safe, we offer a way of configuring this in the framework. Whether a response is considered safe or not is determined by the Dispatcher.

Dispatcher

An implementation of a Dispatcher should be provided by security experts in your project. The Dispatcher is called for every write method of the ResponseWriter and is used to determine whether the passed response should be considered safe. The Dispatcher is responsible for writing the response to the underlying http.ResponseWriter in a safe way.

Go Safe Web provides a DefaultDispatcher implementation which supports github.com/google/safehtml responses.

Warning: the security of the web application depends on a sound Dispatcher implementation. Make sure it is security-reviewed and keep it simple.

Interceptors

Not all security features can be implemented using the Dispatcher alone. For instance, some requests should be rejected before they reach the handler in order to prevent from Cross-site Request Forgery (CSRF, XSRF). To support this, the framework uses Interceptors.

An Interceptor implements methods that run before the request is passed to the handler, and after the handler has committed a response. These are, respectively, Before and Commit.

Life of a Request

To tie it all together, we will explain how a single request goes through the framework.

When the request reaches the server, the following happens:

1. The ServeMux routes the request (i.e. picks the appropriate Handler that will be eventually called). The HTTP method of the request is checked whether it matches any registered Handler.

2. [Before phase] The request is passed to all installed Interceptors, via their Before methods, in the order of installation on the ServeMux. Each of the Before methods can either let the execution continue by returning safehttp.NotWritten() (and not using any ResponseWriter write methods), or by actually writing a response. This would prevent further Before method calls of subsequent Interceptors.

3. The request is passed to the Handler. The Handler calls a write method of the ResponseWriter (e.g. Write, WriteError, Redirect...).

5. [Commit phase] Commit methods of the installed Interceptors are called, in LIFO order (i.e. first Interceptor to be called in Before phase is called last in the Commit phase). Commit methods can no longer influence the flow of the request, but can still set headers, cookies, response HTTP status code or even modify the response (if its type allows it).

6. Dispatcher After all Commit methods have been called, the framework passes the request to the Dispatcher. The Dispatcher determines the Content-Type of the response and whether the response should be considered a Safe Response. The Dispatcher is responsible for writing the response to the underlying http.ResponseWriter in a safe way.

7. The Handler returns the value returned by the ResponseWriter write method used. After the first write, any further writes are considered fatal errors. It is safe to use defer statements for cleanup tasks (e.g. closing a file that was used in a safehtml/template.Template response).

Stack trace of the flow:

Mux.ServeHTTP()
--+ Mux routes the request and checks the method.
--+ InterceptorFoo.Before()
--+ InterceptorBar.Before()
--+ InterceptorBaz.Before()
--+ Handler()
----+ ResponseWriter.Write
------+ InterceptorBaz.Commit()  // notice the inverted order
------+ InterceptorBar.Commit()
------+ InterceptorFoo.Commit()
------+ Dispatcher.Write()
----+ The result of the Response.Write() call is returned.

Error Responses

Error responses are written using ResponseWriter.WriteError. They go through the usual Commit and Dispatcher phases.

Configuring the Mux

TODO

Incremental Adoption

In order to migrate your service using http.Handlers to the safehttp package, we recommend you start doing that one endpoint at a time. Use RegisteredHandler to do this.

safeMuxConfig := /* configured ServeMuxConfig, including interceptors */
safeMuxConfig.Handle("/bar", safehttp.MethodGET, barGETSafeHandler)
safeMuxConfig.Handle("/bar", safehttp.MethodPOST, barPOSTSafeHandler)
safeMuxConfig.Handle("/xyz", safehttp.MethodPOST, xyzSafeHandler)
safeMux := safeMuxConfig.Mux()

// old, not yet migrated
http.Handle("/foo", fooHandler)

// new, migrated
http.Handle("/bar", safehttp.RegisteredHandler(safeMux, "/bar"))
http.Handle("/xyz", safehttp.RegisteredHandler(safeMux, "/xyz"))

Restricting Risky APIs

Some APIs are easy-to-misuse in a security sensitive context. We choose to restrict these and require a security review for their usage in order to prevent vulnerabilities.

cmd/bancheck allows you to restrict APIs and check for their usage as part of the CI/CD pipeline and prevent potentially vulnerable code from being deployed. For detailed usage instructions, please see: https://pkg.go.dev/github.com/google/go-safeweb/cmd/bancheck

Index

Constants

View Source
const (
	MethodConnect = "CONNECT" // RFC 7231, 4.3.6
	MethodDelete  = "DELETE"  // RFC 7231, 4.3.5
	MethodGet     = "GET"     // RFC 7231, 4.3.1
	MethodHead    = "HEAD"    // RFC 7231, 4.3.2
	MethodOptions = "OPTIONS" // RFC 7231, 4.3.7
	MethodPatch   = "PATCH"   // RFC 5789
	MethodPost    = "POST"    // RFC 7231, 4.3.3
	MethodPut     = "PUT"     // RFC 7231, 4.3.4
	MethodTrace   = "TRACE"   // RFC 7231, 4.3.8
)

The HTTP request methods defined by RFC.

Variables

This section is empty.

Functions

func IsLocalDev

func IsLocalDev() bool

IsLocalDev returns whether the framework is set up to use local development rules. Please see the doc on UseLocalDev.

func RegisteredHandler

func RegisteredHandler(mux *ServeMux, pattern string) http.Handler

RegisteredHandler returns the combined (all request methods) handler registered for a given pattern. Returns nil if the exact pattern wasn't used to register any handlers.

This method is helpful for migrating services incrementally, endpoint by endpoint. The handler runs all the installed interceptors and the dispatcher.

Important

This function does not attempt to do any kind of path matching. If the handler was registered using the ServeMuxConfig for a pattern "/foo/", this method will return the handler only when given "/foo/" as an argument, not "/foo" nor "/foo/x".

func UseLocalDev

func UseLocalDev()

UseLocalDev instructs the framework to disable some security mechanisms that would make local development hard or impossible. This cannot be undone without restarting the program and should only be done before any other function or type of the framework is used. This function should ideally be called by the main package immediately after flag parsing. This configuration is not valid for production use.

Types

type Cookie struct {
	// contains filtered or unexported fields
}

A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an HTTP response or the Cookie header of an HTTP request.

See https://tools.ietf.org/html/rfc6265 for details.

func NewCookie

func NewCookie(name, value string) *Cookie

NewCookie creates a new Cookie with safe default settings. Those safe defaults are:

  • Secure: true (if the framework is not in dev mode)
  • HttpOnly: true
  • SameSite: Lax

For more info about all the options, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

func (*Cookie) DisableHTTPOnly

func (c *Cookie) DisableHTTPOnly()

DisableHTTPOnly disables the HttpOnly attribute.

func (*Cookie) DisableSecure

func (c *Cookie) DisableSecure()

DisableSecure disables the secure attribute.

func (*Cookie) Domain

func (c *Cookie) Domain(domain string)

Domain sets the domain attribute.

func (*Cookie) Name

func (c *Cookie) Name() string

Name returns the name of the cookie.

func (*Cookie) Path

func (c *Cookie) Path(path string)

Path sets the path attribute.

func (*Cookie) SameSite

func (c *Cookie) SameSite(s SameSite)

SameSite sets the SameSite attribute.

func (*Cookie) SetMaxAge

func (c *Cookie) SetMaxAge(maxAge int)

SetMaxAge sets the MaxAge attribute.

- MaxAge = 0 means no 'Max-Age' attribute specified. - MaxAge < 0 means delete cookie now, equivalently 'Max-Age: 0' - MaxAge > 0 means Max-Age attribute present and given in seconds

func (*Cookie) String

func (c *Cookie) String() string

String returns the serialization of the cookie for use in a Set-Cookie response header. If c is nil or c.Name() is invalid, the empty string is returned.

func (*Cookie) Value

func (c *Cookie) Value() string

Value returns the value of the cookie.

type DefaultDispatcher

type DefaultDispatcher struct{}

DefaultDispatcher is responsible for writing safe responses.

func (DefaultDispatcher) Error

Error writes the error response to the http.ResponseWriter.

Error sets the Content-Type to "text/plain; charset=utf-8" through calling WriteTextError.

func (DefaultDispatcher) Write

Write writes the response to the http.ResponseWriter if it's deemed safe. It returns a non-nil error if the response is deemed unsafe or if the writing operation fails.

For JSONResponses, the underlying object is serialised and written if it's a valid JSON.

For TemplateResponses, the parsed template is applied to the provided data object. If the funcMap is non-nil, its elements override the existing names to functions mappings in the template. An attempt to define a new name to function mapping that is not already in the template will result in a panic.

Write sets the Content-Type accordingly.

type Dispatcher

type Dispatcher interface {
	// Write writes a Response to the underlying http.ResponseWriter.
	//
	// Write is responsible for setting the Content-Type response header. If the
	// Dispatcher doesn't set the HTTP response status code, the default
	// behavior of http.ResponseWriter applies (i.e. 200 OK is set on first
	// Write).
	//
	// It should return an error if the writing operation fails or if the
	// provided Response should not be written to the http.ResponseWriter
	// because it's unsafe.
	Write(rw http.ResponseWriter, resp Response) error

	// Error writes an ErrorResponse to the underlying http.ResponseWriter.
	//
	// Error is responsible for setting the Content-Type response header and the
	// HTTP response status code.
	//
	// It should return an error if the writing operation fails.
	//
	// Error should always attempt to write a response, no matter what is the
	// underlying type of resp. As a fallback, the Dispatcher can use WriteTextError.
	Error(rw http.ResponseWriter, resp ErrorResponse) error
}

Dispatcher is responsible for writing a response received from the ResponseWriter to the underlying http.ResponseWriter.

The implementation of a custom Dispatcher should be thoroughly reviewed by the security team to avoid introducing vulnerabilities.

type ErrorResponse

type ErrorResponse interface {
	Code() StatusCode
}

ErrorResponse is an HTTP error response. The Dispatcher is responsible for determining whether it is safe.

type FileServerResponse

type FileServerResponse struct {
	// The URL path.
	Path string
	// contains filtered or unexported fields
}

FileServerResponse represents a FileServer response.

func (FileServerResponse) ContentType

func (resp FileServerResponse) ContentType() string

ContentType is the Content-Type of the response.

type Form

type Form struct {
	// contains filtered or unexported fields
}

Form contains parsed data from form parameters, part of the body of POST, PATCH or PUT requests that are not multipart requests.

func (*Form) Bool

func (f *Form) Bool(param string, defaultValue bool) bool

Bool returns the first form parameter value. If the first value is not a valid bool, the defaultValue is returned instead and an error is set (retrievable by Err()).

func (*Form) Err

func (f *Form) Err() error

Err returns nil unless an error occurred while accessing a parsed form value. Calling this method will return the last error that occurred while parsing form values.

func (*Form) Float64

func (f *Form) Float64(param string, defaultValue float64) float64

Float64 returns the first form parameter value. If the first value is not a valid float64, the defaultValue is returned instead and an error is set (retrievable by Err()).

func (*Form) Int64

func (f *Form) Int64(param string, defaultValue int64) int64

Int64 returns the first form parameter value. If the first value is not a valid int64, the defaultValue is returned instead and an error is set (retrievable by Err()).

func (*Form) Slice

func (f *Form) Slice(param string, slicePtr interface{})

Slice returns the form parameter values. If the values don't have the same type, slicePtr will point to a nil slice instead and an error is set (retrievable by Err()). This function should be used in case a form parameter maps to multiple values.

TODO(mihalimara22): Simplify this function to avoid duplicate logic

func (*Form) String

func (f *Form) String(param string, defaultValue string) string

String returns the first form parameter value. If the first value is not a valid string, the defaultValue is returned instead and an error is set (retrievable by Err()).

func (*Form) Uint64

func (f *Form) Uint64(param string, defaultValue uint64) uint64

Uint64 returns the first form parameter value. If the first value is not a valid uint64, the defaultValue is returned instead and an error is set (retrievable by Err()).

type Handler

type Handler interface {
	// ServeHTTP writes the response exactly once, returning the result
	//
	// Except for reading the body, handlers should not modify the provided Request.
	//
	// TODO: Add documentation about error handling when properly implemented.
	ServeHTTP(ResponseWriter, *IncomingRequest) Result
}

Handler responds to an HTTP request.

func FileServer

func FileServer(root string) Handler

FileServer returns a handler that serves HTTP requests with the contents of the file system rooted at root.

func FileServerEmbed

func FileServerEmbed(fs embed.FS) Handler

func StripPrefix

func StripPrefix(prefix string, h Handler) Handler

StripPrefix returns a handler that serves HTTP requests by removing the given prefix from the request URL's Path (and RawPath if set) and invoking the handler h.

StripPrefix handles a request for a path that doesn't begin with prefix by panicking, as this is a server configuration error. The prefix must match exactly (e.g. escaped and unescaped characters are considered different).

type HandlerFunc

type HandlerFunc func(ResponseWriter, *IncomingRequest) Result

HandlerFunc is used to convert a function into a Handler.

func (HandlerFunc) ServeHTTP

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *IncomingRequest) Result

ServeHTTP calls f(w, r).

type Header struct {
	// contains filtered or unexported fields
}

Header represents the key-value pairs in an HTTP header. The keys will be in canonical form, as returned by textproto.CanonicalMIMEHeaderKey.

func NewHeader

func NewHeader(h http.Header) Header

NewHeader creates a new Header.

func (Header) Add

func (h Header) Add(name, value string)

Add adds a new header with the given name and the given value to the collection of headers. The name is first canonicalized using textproto.CanonicalMIMEHeaderKey. It panics when applied on claimed headers or on the Set-Cookie header.

func (Header) Claim

func (h Header) Claim(name string) (set func([]string))

Claim claims the header with the given name and returns a function which can be used to set the header. The name is first canonicalized using textproto.CanonicalMIMEHeaderKey. Other methods in the struct can't write to, change or delete the header with this name. These methods will instead panic when applied on a claimed header. The only way to modify the header is to use the returned function. The Set-Cookie header can't be claimed.

func (Header) Del

func (h Header) Del(name string)

Del deletes all headers with the given name. The name is first canonicalized using textproto.CanonicalMIMEHeaderKey. It panics when applied on claimed headers or on the Set-Cookie header.

func (Header) Get

func (h Header) Get(name string) string

Get returns the value of the first header with the given name. The name is first canonicalized using textproto.CanonicalMIMEHeaderKey. If no header exists with the given name then "" is returned.

func (Header) IsClaimed

func (h Header) IsClaimed(name string) bool

IsClaimed reports whether the provided header is already claimed. The name is first canonicalized using textproto.CanonicalMIMEHeaderKey. The Set-Cookie header is treated as claimed.

func (Header) Set

func (h Header) Set(name, value string)

Set sets the header with the given name to the given value. The name is first canonicalized using textproto.CanonicalMIMEHeaderKey. This method first removes all other values associated with this header before setting the new value. It panics when applied on claimed headers or on the Set-Cookie header.

func (Header) Values

func (h Header) Values(name string) []string

Values returns all the values of all the headers with the given name. The name is first canonicalized using textproto.CanonicalMIMEHeaderKey. The values are returned in the same order as they were sent in the request. The values are returned as a copy of the original slice of strings in the internal header map. This is to prevent modification of the original slice. If no header exists with the given name then an empty slice is returned.

type IncomingRequest

type IncomingRequest struct {
	// Header is the collection of HTTP headers.
	//
	// The Host header is removed from this struct and can be retrieved using Host()
	Header Header
	// TLS is set just like this TLS field of the net/http.Request. For more information
	// see https://pkg.go.dev/net/http?tab=doc#Request.
	TLS *tls.ConnectionState
	// contains filtered or unexported fields
}

IncomingRequest represents an HTTP request received by the server.

func NewIncomingRequest

func NewIncomingRequest(req *http.Request) *IncomingRequest

NewIncomingRequest creates an IncomingRequest from the underlying http.Request.

func (*IncomingRequest) Body

func (r *IncomingRequest) Body() io.ReadCloser

Body returns the request body reader. It is always non-nil but will return EOF immediately when no body is present.

func (*IncomingRequest) Context

func (r *IncomingRequest) Context() context.Context

Context returns the context of a safehttp.IncomingRequest. This is always non-nil and will default to the background context. The context of a safehttp.IncomingRequest is the context of the underlying http.Request.

The context is cancelled when the client's connection closes, the request is canceled (with HTTP/2), or when the ServeHTTP method returns.

func (*IncomingRequest) Cookie

func (r *IncomingRequest) Cookie(name string) (*Cookie, error)

Cookie returns the named cookie provided in the request or net/http.ErrNoCookie if not found. If multiple cookies match the given name, only one cookie will be returned.

func (*IncomingRequest) Cookies

func (r *IncomingRequest) Cookies() []*Cookie

Cookies parses and returns the HTTP cookies sent with the request.

func (*IncomingRequest) Host

func (r *IncomingRequest) Host() string

Host returns the host the request is targeted to. This value comes from the Host header.

func (*IncomingRequest) Method

func (r *IncomingRequest) Method() string

Method returns the HTTP method of the IncomingRequest.

func (*IncomingRequest) MultipartForm

func (r *IncomingRequest) MultipartForm(maxMemory int64) (*MultipartForm, error)

MultipartForm parses the form parameters provided in the body of a POST, PATCH or PUT request that has Content-Type set to multipart/form-data. It returns a MultipartForm object containing the parsed form parameters and file uploads (if any) or the parsing error together with a nil MultipartForm otherwise.

If the parsed request body is larger than maxMemory, up to maxMemory bytes will be stored in main memory, with the rest stored on disk in temporary files.

func (*IncomingRequest) PostForm

func (r *IncomingRequest) PostForm() (*Form, error)

PostForm parses the form parameters provided in the body of a POST, PATCH or PUT request that does not have Content-Type: multipart/form-data. It returns the parsed form parameters as a Form object. If a parsing error occurs it will return it, together with a nil Form. Unless we expect the header Content-Type: multipart/form-data in a POST request, this method should always be used for forms in POST requests.

func (*IncomingRequest) URL

func (r *IncomingRequest) URL() *URL

URL specifies the URL that is parsed from the Request-Line. For most requests, only URL.Path() will return a non-empty result. (See RFC 7230, Section 5.3)

func (*IncomingRequest) WithContext

func (r *IncomingRequest) WithContext(ctx context.Context) *IncomingRequest

WithContext returns a shallow copy of the request with its context changed to ctx. The provided ctx must be non-nil.

This is similar to the net/http.Request.WithContext method.

func (*IncomingRequest) WithStrippedURLPrefix

func (r *IncomingRequest) WithStrippedURLPrefix(prefix string) (*IncomingRequest, error)

WithStrippedURLPrefix returns a shallow copy of the request with its URL stripped of a prefix. The prefix has to match exactly (e.g. escaped and unescaped characters are considered different).

type Interceptor

type Interceptor interface {
	// Before runs before the IncomingRequest is sent to the handler. If a
	// response is written to the ResponseWriter, then the remaining
	// interceptors and the handler won't execute. If Before panics, it will be
	// recovered and the ServeMux will respond with 500 Internal Server Error.
	Before(w ResponseWriter, r *IncomingRequest, cfg InterceptorConfig) Result

	// Commit runs before the response is written by the Dispatcher. If an error
	// is written to the ResponseWriter, then the Commit phases from the
	// remaining interceptors won't execute.
	Commit(w ResponseHeadersWriter, r *IncomingRequest, resp Response, cfg InterceptorConfig)

	// Match checks whether the given config is meant to be applied to the Interceptor.
	Match(InterceptorConfig) bool
}

Interceptor alter the processing of incoming requests.

See the documentation for ServeMux.ServeHTTP to understand how interceptors are run, what happens in case of errors during request processing (i.e. which interceptor methods are guaranteed to be run) etc.

Interceptors keep their state across many requests and their methods can be called concurrently. If you need per-request state, use FlightValues.

type InterceptorConfig

type InterceptorConfig interface{}

InterceptorConfig is a configuration for an interceptor.

type JSONResponse

type JSONResponse struct {
	Data interface{}
}

JSONResponse should encapsulate a valid JSON object that will be serialised and written to the http.ResponseWriter using a JSON encoder.

type Map

type Map interface {
	// Put inserts a key/value pair into the map. If the key already exists in
	// the map, it's value is replaced.
	Put(key, value interface{})
	// Get returns a value for a given key in the map. If the entry with a given
	// key does not exist, nil is returned.
	Get(key interface{}) interface{}
}

Map is a key/value map.

func FlightValues

func FlightValues(ctx context.Context) Map

FlightValues returns a map associated with the given request processing flight. Use it if your interceptors need state that has the lifetime of the request.

type MultipartForm

type MultipartForm struct {
	Form
	// contains filtered or unexported fields
}

MultipartForm extends a parsed multipart form, part of the body of a PATCH, POST or PUT request. A multipart form can include both form values and file uploads, stored either in memory or on disk.

func (*MultipartForm) File

func (f *MultipartForm) File(param string) []*multipart.FileHeader

File returns the file parts associated with form key param or a nil slice, if none. These can be then opened individually by calling FileHeader.Open.

func (*MultipartForm) RemoveFiles

func (f *MultipartForm) RemoveFiles() error

RemoveFiles removes any temporary files associated with a Form and returns the first error that occured, if any.

type NoContentResponse

type NoContentResponse struct{}

NoContentResponse is used to write a "No Content" response.

type RedirectResponse

type RedirectResponse struct {
	// Code is the status to use for the redirect.
	Code StatusCode
	// Location is the value to use for the redirect Location.
	Location string
	// Request is the matching request for which this response is being written.
	// It is used to build the redirect response.
	Request *IncomingRequest
}

RedirectResponse is used to generate redirect responses.

type Response

type Response interface{}

Response should encapsulate the data passed to the ResponseWriter to be written by the Dispatcher. Any implementation of the interface should be supported by the Dispatcher.

type ResponseHeadersWriter

type ResponseHeadersWriter interface {
	// Header returns the collection of headers that will be set
	// on the response. Headers must be set before writing a
	// response (e.g. Write, WriteTemplate).
	Header() Header

	// AddCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
	// The provided cookie must have a valid Name, otherwise an error will be
	// returned.
	AddCookie(c *Cookie) error
}

ResponseHeadersWriter is used to alter the HTTP response headers.

A ResponseHeadersWriter may not be used after the Handler.ServeHTTP method has returned.

type ResponseWriter

type ResponseWriter interface {
	ResponseHeadersWriter

	// Write writes a safe response.
	Write(resp Response) Result

	// WriteError writes an error response (400-599).
	//
	// If the ResponseWriter has already been written to, then this method panics.
	WriteError(resp ErrorResponse) Result
}

ResponseWriter is used to construct an HTTP response. When a Response is passed to the ResponseWriter, it will invoke the Dispatcher with the Response. An attempt to write to the ResponseWriter twice will cause a panic.

A ResponseWriter may not be used after the Handler.ServeHTTP method has returned.

type Result

type Result struct{}

Result is the result of writing an HTTP response.

Use ResponseWriter methods to obtain it.

func ExecuteNamedTemplate

func ExecuteNamedTemplate(w ResponseWriter, t Template, name string, data interface{}) Result

ExecuteNamedTemplate creates a TemplateResponse from the provided Template and its data and calls the Write function of the ResponseWriter, passing the response. Leaving name empty is valid if the template does not have associated templates.

func ExecuteNamedTemplateWithFuncs

func ExecuteNamedTemplateWithFuncs(w ResponseWriter, t Template, name string, data interface{}, fm map[string]interface{}) Result

ExecuteNamedTemplateWithFuncs creates a TemplateResponse from the provided Template, its data and the name to function mappings and calls the Write function of the ResponseWriter, passing the response. Leaving name empty is valid if the template does not have associated templates.

func ExecuteTemplate

func ExecuteTemplate(w ResponseWriter, t Template, data interface{}) Result

ExecuteTemplate creates a TemplateResponse from the provided Template and its data and calls the Write function of the ResponseWriter, passing the response.

func ExecuteTemplateWithFuncs

func ExecuteTemplateWithFuncs(w ResponseWriter, t Template, data interface{}, fm map[string]interface{}) Result

ExecuteTemplateWithFuncs creates a TemplateResponse from the provided Template, its data and the name to function mappings and calls the Write function of the ResponseWriter, passing the response. Leaving name empty is valid if the template does not have associated templates.

func NotWritten

func NotWritten() Result

NotWritten returns a Result which indicates that nothing has been written yet. It can be used in all functions that return a Result, such as in the ServeHTTP method of a Handler or in the Before method of an Interceptor. When returned, NotWritten indicates that the writing of the response should take place later. When this is returned by the Before method in Interceptors the next Interceptor in line is run. When this is returned by a Handler, a 204 No Content response is written.

func Redirect

func Redirect(w ResponseWriter, r *IncomingRequest, location string, code StatusCode) Result

Redirect creates a RedirectResponse and writes it to w. If the given code is not a valid Redirect code this function will panic.

func WriteJSON

func WriteJSON(w ResponseWriter, data interface{}) Result

WriteJSON creates a JSONResponse from the data object and calls the Write function of the ResponseWriter, passing the response. The data object should be valid JSON, otherwise an error will occur.

type SameSite

type SameSite int

SameSite allows a server to define a cookie attribute making it impossible for the browser to send this cookie along with cross-site requests. The main goal is to mitigate the risk of cross-origin information leakage, and provide some protection against cross-site request forgery attacks.

See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00 for details.

const (
	// SameSiteLaxMode allows sending cookies with same-site requests and
	// cross-site top-level navigations.
	SameSiteLaxMode SameSite = iota + 1
	// SameSiteStrictMode allows sending cookie only with same-site requests.
	SameSiteStrictMode
	// SameSiteNoneMode allows sending cookies with all requests, including the
	// ones made cross-origin.
	SameSiteNoneMode
)

type ServeMux

type ServeMux struct {
	// contains filtered or unexported fields
}

ServeMux is an HTTP request multiplexer. It matches the URL of each incoming request against a list of registered patterns and calls the handler for the pattern that most closely matches the URL.

Patterns names are fixed, rooted paths, like "/favicon.ico", or rooted subtrees like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.

Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".

If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering "/images/" causes ServeMux to redirect a request for "/images" to "/images/", unless "/images" has been registered separately.

Patterns may optionally begin with a host name, restricting matches to URLs on that host only. Host-specific patterns take precedence over general patterns, so that a handler might register for the two patterns "/codesearch" and "codesearch.google.com/" without also taking over requests for "http://www.google.com/".

ServeMux also takes care of sanitizing the URL request path and the Host header, stripping the port number and redirecting any request containing . or .. elements or repeated slashes to an equivalent, cleaner URL.

Multiple handlers can be registered for a single pattern, as long as they handle different HTTP methods.

func (*ServeMux) Handle

func (m *ServeMux) Handle(pattern string, method string, h Handler, cfgs ...InterceptorConfig)

Handle registers a handler for the given pattern and method. If a handler is registered twice for the same pattern and method, Build will panic.

InterceptorConfigs can be passed in order to modify the behavior of the interceptors on a registered handler. Passing an InterceptorConfig whose corresponding Interceptor was not installed will produce no effect. If multiple configurations are passed for the same Interceptor, Mux will panic.

func (*ServeMux) ServeHTTP

func (m *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP dispatches the request to the handler whose method matches the incoming request and whose pattern most closely matches the request URL.

For each incoming request:
- [Before Phase] Interceptor.Before methods are called for every installed
  interceptor, until an interceptor writes to a ResponseWriter (including
  errors) or panics,
- the handler is called after a [Before Phase] if no writes or panics occured,
- the handler triggers the [Commit Phase] by writing to the ResponseWriter,
- [Commit Phase] Interceptor.Commit methods run for every interceptor whose
  Before method was called,
- [Dispatcher Phase] after the [Commit Phase], the Dispatcher's appropriate
  write method is called; the Dispatcher is responsible for determining whether
  the response is indeed safe and writing it,
- if the handler attempts to write more than once, it is treated as an
  unrecoverable error; the request processing ends abrubptly with a panic and
  nothing else happens (note: this will change as soon as [After Phase] is
  introduced)

Interceptors should NOT rely on the order they're run.

type ServeMuxConfig

type ServeMuxConfig struct {
	// contains filtered or unexported fields
}

ServeMuxConfig is a builder for ServeMux.

func NewServeMuxConfig

func NewServeMuxConfig(disp Dispatcher) *ServeMuxConfig

NewServeMuxConfig crates a ServeMuxConfig with the provided Dispatcher. If the provided Dispatcher is nil, the DefaultDispatcher is used.

func (*ServeMuxConfig) Clone

func (s *ServeMuxConfig) Clone() *ServeMuxConfig

Clone creates a copy of the current config. This can be used to create several instances of Mux that share the same set of plugins.

func (*ServeMuxConfig) HandleMethodNotAllowed

func (s *ServeMuxConfig) HandleMethodNotAllowed(h Handler, cfgs ...InterceptorConfig)

HandleMethodNotAllowed registers a handler that runs when a given method is not allowed for a registered path.

func (*ServeMuxConfig) Intercept

func (s *ServeMuxConfig) Intercept(is ...Interceptor)

Intercept installs the given interceptors.

Interceptors order is respected and interceptors are always run in the order they've been installed.

Calling Intercept multiple times is valid. Interceptors that are added last will run last.

func (*ServeMuxConfig) Mux

func (s *ServeMuxConfig) Mux() *ServeMux

Mux returns the ServeMux with a copy of the current configuration.

type Server

type Server struct {
	// Addr optionally specifies the TCP address for the server to listen on,
	// in the form "host:port". If empty, ":http" (port 80) is used.
	// The service names are defined in RFC 6335 and assigned by IANA.
	// See net.Dial for details of the address format.
	Addr string

	// Mux is the ServeMux to use for the current server. A nil Mux is invalid.
	Mux *ServeMux

	// ReadTimeout is the maximum duration for reading the entire
	// request, including the body.
	ReadTimeout time.Duration

	// WriteTimeout is the maximum duration before timing out
	// writes of the response. It is reset whenever a new
	// request's header is read.
	WriteTimeout time.Duration

	// IdleTimeout is the maximum amount of time to wait for the
	// next request when keep-alives are enabled.
	IdleTimeout time.Duration

	// MaxHeaderBytes controls the maximum number of bytes the
	// server will read parsing the request header's keys and
	// values, including the request line. It does not limit the
	// size of the request body.
	MaxHeaderBytes int

	// TLSConfig optionally provides a TLS configuration for use
	// by ServeTLS and ListenAndServeTLS. Note that this value is
	// cloned on serving, so it's not possible to modify the
	// configuration with methods like tls.Config.SetSessionTicketKeys.
	//
	// When the server is started the cloned configuration will be changed
	// to set the minimum TLS version to 1.2 and to prefer Server Ciphers.
	TLSConfig *tls.Config

	// OnShutdown is a slice of functions to call on Shutdown.
	// This can be used to gracefully shutdown connections that have undergone
	// ALPN protocol upgrade or that have been hijacked.
	// These functions should start protocol-specific graceful shutdown, but
	// should not wait for shutdown to complete.
	OnShudown []func()

	// DisableKeepAlives controls whether HTTP keep-alives should be disabled.
	DisableKeepAlives bool
	// contains filtered or unexported fields
}

Server is a safe wrapper for a standard HTTP server. The zero value is safe and ready to use and will apply safe defaults on serving. Changing any of the fields after the server has been started is a no-op.

func (*Server) Clone

func (s *Server) Clone() *Server

Clone returns an unstarted deep copy of Server that can be re-configured and re-started.

func (*Server) Close

func (s *Server) Close() error

Close is a wrapper for https://golang.org/pkg/net/http/#Server.Close

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe is a wrapper for https://golang.org/pkg/net/http/#Server.ListenAndServe

func (*Server) ListenAndServeTLS

func (s *Server) ListenAndServeTLS(certFile, keyFile string) error

ListenAndServeTLS is a wrapper for https://golang.org/pkg/net/http/#Server.ListenAndServeTLS

func (*Server) Serve

func (s *Server) Serve(l net.Listener) error

Serve is a wrapper for https://golang.org/pkg/net/http/#Server.Serve

func (*Server) ServeTLS

func (s *Server) ServeTLS(l net.Listener, certFile, keyFile string) error

ServeTLS is a wrapper for https://golang.org/pkg/net/http/#Server.ServeTLS

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown is a wrapper for https://golang.org/pkg/net/http/#Server.Shutdown

type StatusCode

type StatusCode int

StatusCode contains HTTP status codes as registered with IANA. See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

const (
	StatusContinue           StatusCode = 100 // RFC 7231, 6.2.1
	StatusSwitchingProtocols StatusCode = 101 // RFC 7231, 6.2.2
	StatusProcessing         StatusCode = 102 // RFC 2518, 10.1
	StatusEarlyHints         StatusCode = 103 // RFC 8297

	StatusOK                   StatusCode = 200 // RFC 7231, 6.3.1
	StatusCreated              StatusCode = 201 // RFC 7231, 6.3.2
	StatusAccepted             StatusCode = 202 // RFC 7231, 6.3.3
	StatusNonAuthoritativeInfo StatusCode = 203 // RFC 7231, 6.3.4
	StatusNoContent            StatusCode = 204 // RFC 7231, 6.3.5
	StatusResetContent         StatusCode = 205 // RFC 7231, 6.3.6
	StatusPartialContent       StatusCode = 206 // RFC 7233, 4.1
	StatusMultiStatus          StatusCode = 207 // RFC 4918, 11.1
	StatusAlreadyReported      StatusCode = 208 // RFC 5842, 7.1
	StatusIMUsed               StatusCode = 226 // RFC 3229, 10.4.1

	StatusMultipleChoice   StatusCode = 300 // RFC 7231, 6.4.1
	StatusMovedPermanently StatusCode = 301 // RFC 7231, 6.4.2
	StatusFound            StatusCode = 302 // RFC 7231, 6.4.3
	StatusSeeOther         StatusCode = 303 // RFC 7231, 6.4.4
	StatusNotModified      StatusCode = 304 // RFC 7232, 4.1
	StatusUseProxy         StatusCode = 305 // RFC 7231, 6.4.5

	StatusTemporaryRedirect StatusCode = 307 // RFC 7231, 6.4.7
	StatusPermanentRedirect StatusCode = 308 // RFC 7538, 3

	StatusBadRequest                   StatusCode = 400 // RFC 7231, 6.5.1
	StatusUnauthorized                 StatusCode = 401 // RFC 7235, 3.1
	StatusPaymentRequired              StatusCode = 402 // RFC 7231, 6.5.2
	StatusForbidden                    StatusCode = 403 // RFC 7231, 6.5.3
	StatusNotFound                     StatusCode = 404 // RFC 7231, 6.5.4
	StatusMethodNotAllowed             StatusCode = 405 // RFC 7231, 6.5.5
	StatusNotAcceptable                StatusCode = 406 // RFC 7231, 6.5.6
	StatusProxyAuthRequired            StatusCode = 407 // RFC 7235, 3.2
	StatusRequestTimeout               StatusCode = 408 // RFC 7231, 6.5.7
	StatusConflict                     StatusCode = 409 // RFC 7231, 6.5.8
	StatusGone                         StatusCode = 410 // RFC 7231, 6.5.9
	StatusLengthRequired               StatusCode = 411 // RFC 7231, 6.5.10
	StatusPreconditionFailed           StatusCode = 412 // RFC 7232, 4.2
	StatusRequestEntityTooLarge        StatusCode = 413 // RFC 7231, 6.5.11
	StatusRequestURITooLong            StatusCode = 414 // RFC 7231, 6.5.12
	StatusUnsupportedMediaType         StatusCode = 415 // RFC 7231, 6.5.13
	StatusRequestedRangeNotSatisfiable StatusCode = 416 // RFC 7233, 4.4
	StatusExpectationFailed            StatusCode = 417 // RFC 7231, 6.5.14
	StatusTeapot                       StatusCode = 418 // RFC 7168, 2.3.3
	StatusMisdirectedRequest           StatusCode = 421 // RFC 7540, 9.1.2
	StatusUnprocessableEntity          StatusCode = 422 // RFC 4918, 11.2
	StatusLocked                       StatusCode = 423 // RFC 4918, 11.3
	StatusFailedDependency             StatusCode = 424 // RFC 4918, 11.4
	StatusTooEarly                     StatusCode = 425 // RFC 8470, 5.2.
	StatusUpgradeRequired              StatusCode = 426 // RFC 7231, 6.5.15
	StatusPreconditionRequired         StatusCode = 428 // RFC 6585, 3
	StatusTooManyRequests              StatusCode = 429 // RFC 6585, 4
	StatusRequestHeaderFieldsTooLarg   StatusCode = 431 // RFC 6585, 5
	StatusUnavailableForLegalReasons   StatusCode = 451 // RFC 7725, 3

	StatusInternalServerError           StatusCode = 500 // RFC 7231, 6.6.1
	StatusNotImplemented                StatusCode = 501 // RFC 7231, 6.6.2
	StatusBadGateway                    StatusCode = 502 // RFC 7231, 6.6.3
	StatusServiceUnavailable            StatusCode = 503 // RFC 7231, 6.6.4
	StatusGatewayTimeout                StatusCode = 504 // RFC 7231, 6.6.5
	StatusHTTPVersionNotSupported       StatusCode = 505 // RFC 7231, 6.6.6
	StatusVariantAlsoNegotiates         StatusCode = 506 // RFC 2295, 8.1
	StatusInsufficientStorage           StatusCode = 507 // RFC 4918, 11.5
	StatusLoopDetected                  StatusCode = 508 // RFC 5842, 7.2
	StatusNotExtended                   StatusCode = 510 // RFC 2774, 7
	StatusNetworkAuthenticationRequired StatusCode = 511 // RFC 6585, 6
)

The HTTP status codes registered with IANA.

func (StatusCode) Code

func (c StatusCode) Code() StatusCode

Code implements ErrorResponse.

func (StatusCode) String

func (c StatusCode) String() string

type Template

type Template interface {
	// Execute applies data to the template and then writes the result to
	// the io.Writer.
	//
	// Execute returns an error if applying the data object to the
	// Template fails or if an error occurs while writing the result to the
	// io.Writer.
	Execute(wr io.Writer, data interface{}) error

	// ExecuteTemplate applies the named associated template to the specified data
	// object and writes the output to the io.Writer.
	//
	// ExecuteTemplate returns an error if applying the data object to the
	// Template fails or if an error occurs while writing the result to the
	// io.Writer.
	ExecuteTemplate(wr io.Writer, name string, data interface{}) error
}

Template implements a template.

type TemplateResponse

type TemplateResponse struct {
	Template Template
	Name     string
	Data     interface{}
	FuncMap  map[string]interface{}
}

TemplateResponse bundles a Template with its data and names to function mappings to be passed together to the commit phase.

type URL

type URL struct {
	// contains filtered or unexported fields
}

URL represents a parsed URL (technically, a URI reference).

func ParseURL

func ParseURL(rawurl string) (*URL, error)

ParseURL parses a raw URL string into a URL structure.

The raw URl may be relative (a path, without a host) or absolute (starting with a scheme). Trying to parse a hostname and path without a scheme is invalid but may not necessarily return an error, due to parsing ambiguities.

func (URL) Host

func (u URL) Host() string

Host returns the host or the host:port of the URL.

func (URL) Hostname

func (u URL) Hostname() string

Hostname returns the host of the URL, stripping any valid port number if present.

If the result is enclosed in square brackets, as literal IPv6 addresses are, the square brackets are removed from the result.

func (URL) Path

func (u URL) Path() string

Path returns the path of the URL.

Note that the path is stored in decoded form: /%47%6f%2f becomes /Go/. A consequence is that it is impossible to tell which slashes in the path were slashes in the rawURL and which were %2f.

func (URL) Port

func (u URL) Port() string

Port returns the port part of the URL. If the host doesn't contain a valid port number, Port returns an empty string.

func (URL) Query

func (u URL) Query() (Form, error)

Query parses the query string in the URL and returns a form containing its values. The returned error describes the first decoding error encountered, if any.

func (URL) String

func (u URL) String() string

String reassembles the URL into a valid URL string.

The method uses the net/url.EscapedPath method to obtain the path. See the net/url.EscapedPath method for more details.

Directories

Path Synopsis
Package defaults provides ready to use, safe, pre-configured instances of safehttp types.
Package defaults provides ready to use, safe, pre-configured instances of safehttp types.
Package internal contains internal APIs.
Package internal contains internal APIs.
plugins
collector
Package collector provides a function for creating violation report handlers.
Package collector provides a function for creating violation report handlers.
coop
Package coop provides Cross-Origin-Opener-Policy protection.
Package coop provides Cross-Origin-Opener-Policy protection.
cors
Package cors provides a safehttp.Interceptor that handles CORS requests.
Package cors provides a safehttp.Interceptor that handles CORS requests.
csp
Package csp provides a safehttp.Interceptor which applies Content-Security Policies to responses.
Package csp provides a safehttp.Interceptor which applies Content-Security Policies to responses.
csp/internalunsafecsp
Package internalunsafecsp is used internally to override CSP.
Package internalunsafecsp is used internally to override CSP.
csp/internalunsafecsp/unsafecspfortests
Package unsafecspfortests can be used to disable CSP on specific handler registration in tests.
Package unsafecspfortests can be used to disable CSP on specific handler registration in tests.
csp/internalunsafecsp/unsafestrictcsp
Package unsafestrictcsp can be used to disable Strict CSP protections on specific handler registration.
Package unsafestrictcsp can be used to disable Strict CSP protections on specific handler registration.
csp/internalunsafecsp/unsafetrustedtypes
Package unsafetrustedtypes can be used to disable Trusted Types protections on specific handler registration.
Package unsafetrustedtypes can be used to disable Trusted Types protections on specific handler registration.
fetchmetadata
Package fetchmetadata provides Fetch-Metadata based protections.
Package fetchmetadata provides Fetch-Metadata based protections.
fetchmetadata/internalunsafefetchmetadata
Package internalunsafefetchmetadata is used internally to override FM policies.
Package internalunsafefetchmetadata is used internally to override FM policies.
fetchmetadata/internalunsafefetchmetadata/unsafefetchmetadatafortests
Package unsafefetchmetadatafortests can be used to disable Fetch Metadata protections on specific handler registration in tests.
Package unsafefetchmetadatafortests can be used to disable Fetch Metadata protections on specific handler registration in tests.
fetchmetadata/internalunsafefetchmetadata/unsaferesourcepolicy
Package unsaferesourcepolicy can be used to disable Fetch Metadata protections on specific handler registration.
Package unsaferesourcepolicy can be used to disable Fetch Metadata protections on specific handler registration.
framing
Package framing provides utilities to install a comprehensive framing protection.
Package framing provides utilities to install a comprehensive framing protection.
framing/internalunsafeframing
Package internalunsafeframing is used internally to override Framing protections.
Package internalunsafeframing is used internally to override Framing protections.
framing/internalunsafeframing/unsafeframing
Package unsafeframing can be used to disable Framing protections on specific handler registration.
Package unsafeframing can be used to disable Framing protections on specific handler registration.
framing/internalunsafeframing/unsafeframingfortests
Package unsafeframingfortests can be used to disable Framing protections on specific handler registration in tests.
Package unsafeframingfortests can be used to disable Framing protections on specific handler registration in tests.
hostcheck
Package hostcheck provides a plugin that checks whether the request is intended to be sent to a given host.
Package hostcheck provides a plugin that checks whether the request is intended to be sent to a given host.
hsts
Package hsts provides HTTP Strict Transport Security.
Package hsts provides HTTP Strict Transport Security.
htmlinject
Package htmlinject provides utilities to pre-process HTML templates and inject additional parts into them before parsing.
Package htmlinject provides utilities to pre-process HTML templates and inject additional parts into them before parsing.
reportingapi
Package reportingapi is an implementation of the Report-To header described in https://www.w3.org/TR/reporting/#header.
Package reportingapi is an implementation of the Report-To header described in https://www.w3.org/TR/reporting/#header.
staticheaders
Package staticheaders provides a safehttp.Interceptor which sets security sensitive headers on every response.
Package staticheaders provides a safehttp.Interceptor which sets security sensitive headers on every response.
xsrf
Package xsrf contains helper functions for the safehttp.Interceptor that provide protection against Cross-Site Request Forgery attacks.
Package xsrf contains helper functions for the safehttp.Interceptor that provide protection against Cross-Site Request Forgery attacks.
xsrf/xsrfangular
Package xsrfangular provides a safehttp.Interceptor that ensures Cross-Site Request Forgery protection for Angular applications by verifying the incoming requests, rejecting those requests that are suspected to be part of an attack.
Package xsrfangular provides a safehttp.Interceptor that ensures Cross-Site Request Forgery protection for Angular applications by verifying the incoming requests, rejecting those requests that are suspected to be part of an attack.
xsrf/xsrfhtml
Package xsrfhtml provides a safehttp.Interceptor that ensures Cross-Site Request Forgery by verifying the incoming requests for the presence of an XSRF token, rejecting those requests that are suspected to be part of an attack.
Package xsrfhtml provides a safehttp.Interceptor that ensures Cross-Site Request Forgery by verifying the incoming requests for the presence of an XSRF token, rejecting those requests that are suspected to be part of an attack.
Package restricted contains restricted APIs.
Package restricted contains restricted APIs.
Package safehttptest provides utilities for testing safehttp.Handler:s and safehttp.Interceptor:s.
Package safehttptest provides utilities for testing safehttp.Handler:s and safehttp.Interceptor:s.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL