Documentation
¶
Index ¶
- Variables
- func BodyLimit(cfg BodyLimitConfig, skippers ...Skipper) func(keratin.Handler) keratin.Handler
- func BodyRereadable(skippers ...Skipper) func(keratin.Handler) keratin.Handler
- func CORS(cfg CORSConfig, skippers ...Skipper) func(http.Handler) http.Handler
- func CSRF(cfg CSRFConfig, skippers ...Skipper) func(keratin.Handler) keratin.Handler
- func CheckMethod(method, pattern string) (string, bool)
- func CtxCSRF(ctx context.Context) string
- func CtxRequestID(ctx context.Context) string
- func HTTPRecover(cfg RecoverConfig, logger *slog.Logger) func(next http.Handler) http.Handler
- func Recover(cfg RecoverConfig) func(keratin.Handler) keratin.Handler
- func RequestID(cfg RequestIDConfig, skippers ...Skipper) func(keratin.Handler) keratin.Handler
- func RequestLogger(cfg RequestLoggerConfig, skippers ...Skipper) func(keratin.Handler) keratin.Handler
- func Secure(cfg SecureConfig, skippers ...Skipper) func(keratin.Handler) keratin.Handler
- type BodyLimitConfig
- type CORSConfig
- type CSRFConfig
- type ErrorStatusFunc
- type ExtractorSource
- type RecoverConfig
- type RequestIDConfig
- type RequestLoggerAttrsFunc
- type RequestLoggerConfig
- type RequestMetadata
- type SecureConfig
- type Skipper
- type ValueExtractorError
- type ValuesExtractor
Constants ¶
This section is empty.
Variables ¶
var DefaultSecureConfig = SecureConfig{
XSSProtection: "1; mode=block",
ContentTypeNosniff: "nosniff",
XFrameOptions: "SAMEORIGIN",
}
var ErrCSRFInvalid = keratin.NewHTTPError(http.StatusForbidden, "invalid csrf token")
ErrCSRFInvalid is returned when CSRF check fails
Functions ¶
func BodyRereadable ¶
func CheckMethod ¶
func CtxRequestID ¶
func HTTPRecover ¶
func RequestID ¶
RequestID returns a middleware that reads RequestIDConfig.TargetHeader (`X-Request-ID`) header value or when the header value is empty, generates that value and sets request ID to response as RequestIDConfig.TargetHeader (`X-Request-Id`) value.
func RequestLogger ¶
Types ¶
type BodyLimitConfig ¶
type BodyLimitConfig struct {
// Maximum allowed size for a request body, default is 32MB.
// If Limit is less to 0, no limit is applied.
Limit int64 `env:"LIMIT" json:"limit,omitempty" yaml:"limit,omitempty"`
}
func (*BodyLimitConfig) SetDefaults ¶
func (c *BodyLimitConfig) SetDefaults()
type CORSConfig ¶
type CORSConfig struct {
// AllowOrigins determines the value of the Access-Control-Allow-Origin
// response header. This header defines a list of origins that may access the
// resource.
//
// Origin consist of following parts: `scheme + "://" + host + optional ":" + port`
// Wildcard can be used, but has to be set explicitly []string{"*"}
// Example: `https://example.com`, `http://example.com:8080`, `*`
//
// Security: use extreme caution when handling the origin, and carefully
// validate any logic. Remember that attackers may register hostile domain names.
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
//
// Mandatory.
AllowOrigins []string `env:"ALLOW_ORIGINS" json:"allowOrigins,omitempty" yaml:"allowOrigins,omitempty"`
// UnsafeAllowOriginFunc is an optional custom function to validate the origin. It takes the
// origin as an argument and returns
// - string, allowed origin
// - bool, true if allowed or false otherwise.
// - error, if an error is returned, it is returned immediately by the handler.
// If this option is set, AllowOrigins is ignored.
//
// Security: use extreme caution when handling the origin, and carefully
// validate any logic. Remember that attackers may register hostile (sub)domain names.
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
//
// Sub-domain checks example:
// UnsafeAllowOriginFunc: func(r *http.Request, origin string) (string, bool, error) {
// if strings.HasSuffix(origin, ".example.com") {
// return origin, true, nil
// }
// return "", false, nil
// },
//
// Optional.
UnsafeAllowOriginFunc func(r *http.Request, origin string) (allowedOrigin string, allowed bool, err error) `json:"-" yaml:"-"`
// AllowMethods determines the value of the Access-Control-Allow-Methods
// response header. This header specified the list of methods allowed when
// accessing the resource. This is used in response to a preflight request.
//
// If `allowMethods` is left empty, this middleware will fill for preflight
// request `Access-Control-Allow-Methods` header value
// from `Allow` header that keratin.Router set into request context.
//
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
AllowMethods []string `env:"ALLOW_METHODS" json:"allowMethods,omitempty" yaml:"allowMethods,omitempty"`
// AllowHeaders determines the value of the Access-Control-Allow-Headers
// response header. This header is used in response to a preflight request to
// indicate which HTTP headers can be used when making the actual request.
//
// Optional. Defaults to empty list. No domains allowed for CORS.
//
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
AllowHeaders []string `env:"ALLOW_HEADERS" json:"allowHeaders,omitempty" yaml:"allowHeaders,omitempty"`
// AllowCredentials determines the value of the
// Access-Control-Allow-Credentials response header. This header indicates
// whether or not the response to the request can be exposed when the
// credentials mode (Request.credentials) is true. When used as part of a
// response to a preflight request, this indicates whether or not the actual
// request can be made using credentials. See also
// [MDN: Access-Control-Allow-Credentials].
//
// Optional. Default value false, in which case the header is not set.
//
// Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`.
// See "Exploiting CORS misconfigurations for Bitcoins and bounties",
// https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
//
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
AllowCredentials bool `env:"ALLOW_CREDENTIALS" json:"allowCredentials,omitempty" yaml:"allowCredentials,omitempty"`
// ExposeHeaders determines the value of Access-Control-Expose-Headers, which
// defines a list of headers that clients are allowed to access.
//
// Optional. Default value []string{}, in which case the header is not set.
//
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Header
ExposeHeaders []string `env:"EXPOSE_HEADERS" json:"exposeHeaders,omitempty" yaml:"exposeHeaders,omitempty"`
// MaxAge determines the value of the Access-Control-Max-Age response header.
// This header indicates how long (in seconds) the results of a preflight
// request can be cached.
// The header is set only if MaxAge != 0, negative value sends "0" which instructs browsers not to cache that response.
//
// Optional. Default value 0 - meaning header is not sent.
//
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
MaxAge int `env:"MAX_AGE" json:"maxAge,omitempty" yaml:"maxAge,omitempty"`
}
type CSRFConfig ¶
type CSRFConfig struct {
// TrustedOrigin permits any request with `Sec-Fetch-Site` header whose `Origin` header
// exactly matches the specified value.
// Values should be formated as Origin header "scheme://host[:port]".
//
// See [Origin]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
// See [Sec-Fetch-Site]: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#fetch-metadata-headers
TrustedOrigins []string `env:"TRUSTED_ORIGINS" json:"trustedOrigins,omitempty" yaml:"trustedOrigins,omitempty"`
// AllowSecFetchSameSite allows custom behaviour for `Sec-Fetch-Site` requests that are about to
// fail with CRSF error, to be allowed or replaced with custom error.
// This function applies to `Sec-Fetch-Site` values:
// - `same-site` same registrable domain (subdomain and/or different port)
// - `cross-site` request originates from different site
// See [Sec-Fetch-Site]: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#fetch-metadata-headers
AllowSecFetchSiteFunc func(r *http.Request) (bool, error) `json:"-" yaml:"-"`
// TokenLength is the length of the generated token.
TokenLength uint8 `env:"TOKEN_LENGTH" json:"tokenLength,omitempty" yaml:"tokenLength,omitempty"`
// TokenLookup is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used
// to extract token from the request.
// Optional. Default value "header:X-CSRF-Token".
// Possible values:
// - "header:<name>" or "header:<name>:<cut-prefix>"
// - "query:<name>"
// - "form:<name>"
// Multiple sources example:
// - "header:X-CSRF-Token,query:csrf"
TokenLookup string `env:"TOKEN_LOOKUP" json:"tokenLookup,omitempty" yaml:"tokenLookup,omitempty"`
// Generator defines a function to generate token.
// Optional. Defaults tp randomString(TokenLength).
Generator func() string `json:"-" yaml:"-"`
// Name of the CSRF cookie. This cookie will store CSRF token.
// Optional. Default value "csrf".
CookieName string `env:"COOKIE_NAME" json:"cookieName,omitempty" yaml:"cookieName,omitempty"`
// Domain of the CSRF cookie.
// Optional. Default value none.
CookieDomain string `env:"COOKIE_DOMAIN" json:"cookieDomain,omitempty" yaml:"cookieDomain,omitempty"`
// Path of the CSRF cookie.
// Optional. Default value none.
CookiePath string `env:"COOKIE_PATH" json:"cookiePath,omitempty" yaml:"cookiePath,omitempty"`
// Max age (in seconds) of the CSRF cookie.
// Optional. Default value 86400 (24hr).
CookieMaxAge int `env:"COOKIE_MAX_AGE" json:"cookieMaxAge,omitempty" yaml:"cookieMaxAge,omitempty"`
// Indicates if CSRF cookie is secure.
// Optional. Default value false.
CookieSecure bool `env:"COOKIE_SECURE" json:"cookieSecure,omitempty" yaml:"cookieSecure,omitempty"`
// Indicates if CSRF cookie is HTTP only.
// Optional. Default value false.
CookieHTTPOnly bool `env:"COOKIE_HTTP_ONLY" json:"cookieHTTPOnly,omitempty" yaml:"cookieHTTPOnly,omitempty"`
// Indicates SameSite mode of the CSRF cookie.
// Optional. Default value SameSiteDefaultMode.
CookieSameSite http.SameSite `env:"COOKIE_SAME_SITE" json:"cookieSameSite,omitempty" yaml:"cookieSameSite,omitempty"`
// ErrorHandler defines a function which is executed for returning custom errors.
ErrorHandler func(r *http.Request, err error) error `json:"-" yaml:"-"`
}
func (*CSRFConfig) SetDefaults ¶
func (c *CSRFConfig) SetDefaults()
type ErrorStatusFunc ¶
ErrorStatusFunc return an error code.
type ExtractorSource ¶
type ExtractorSource string
ExtractorSource is type to indicate source for extracted value
const ( // ExtractorSourceHeader means value was extracted from request header ExtractorSourceHeader ExtractorSource = "header" // ExtractorSourceQuery means value was extracted from request query parameters ExtractorSourceQuery ExtractorSource = "query" // ExtractorSourcePathParam means value was extracted from route path parameters ExtractorSourcePathParam ExtractorSource = "param" // ExtractorSourceCookie means value was extracted from request cookies ExtractorSourceCookie ExtractorSource = "cookie" // ExtractorSourceForm means value was extracted from request form values ExtractorSourceForm ExtractorSource = "form" )
type RecoverConfig ¶
type RecoverConfig struct {
// Size of the stack to be printed.
// Optional. Default value 2KB.
StackSize int `env:"STACK_SIZE" json:"stackSize,omitempty" yaml:"stackSize,omitempty"`
}
func (*RecoverConfig) SetDefaults ¶
func (c *RecoverConfig) SetDefaults()
type RequestIDConfig ¶
type RequestIDConfig struct {
// Generator defines a function to generate an ID.
// Optional. Default value random.String(32).
Generator func() string
// TargetHeader defines what header to look for to populate the id.
// Optional. Default value is `X-Request-Id`
TargetHeader string
}
RequestIDConfig defines the config for RequestID middleware.
func (*RequestIDConfig) SetDefaults ¶
func (c *RequestIDConfig) SetDefaults()
type RequestLoggerAttrsFunc ¶
type RequestLoggerAttrsFunc func(w http.ResponseWriter, r *http.Request, metadata RequestMetadata) []slog.Attr
RequestLoggerAttrsFunc defines a function type for generating logging attributes based on HTTP request and response.
func RequestLoggerAttrs ¶
func RequestLoggerAttrs() RequestLoggerAttrsFunc
type RequestLoggerConfig ¶
type RequestLoggerConfig struct {
// RequestLoggerAttrsFunc defines a function type for generating logging attributes based on HTTP request and response.
RequestLoggerAttrsFunc `json:"-" yaml:"-"`
// ErrorStatusFunc return an error code.
ErrorStatusFunc `json:"-" yaml:"-"`
// Logger is the logger used to log the request.
Logger *slog.Logger `json:"-" yaml:"-"`
}
func (*RequestLoggerConfig) SetDefaults ¶
func (c *RequestLoggerConfig) SetDefaults()
type RequestMetadata ¶
type SecureConfig ¶
type SecureConfig struct {
// XSSProtection provides protection against cross-site scripting attack (XSS)
// by setting the `X-XSS-Protection` header.
// Optional. Default value "".
XSSProtection string `env:"XSS_PROTECTION" json:"xssProtection,omitempty" yaml:"xssProtection,omitempty"`
// ContentTypeNosniff provides protection against overriding Content-Type
// header by setting the `X-Content-Type-Options` header.
// Optional. Default value "".
ContentTypeNosniff string `env:"CONTENT_TYPE_NOSNIFF" json:"contentTypeNosniff,omitempty" yaml:"contentTypeNosniff,omitempty"`
// XFrameOptions can be used to indicate whether or not a browser should
// be allowed to render a page in a <frame>, <iframe> or <object> .
// Sites can use this to avoid clickjacking attacks, by ensuring that their
// content is not embedded into other sites.provides protection against
// clickjacking.
// Optional. Default value "".
// Possible values:
// - "SAMEORIGIN" - The page can only be displayed in a frame on the same origin as the page itself.
// - "DENY" - The page cannot be displayed in a frame, regardless of the site attempting to do so.
// - "ALLOW-FROM uri" - The page can only be displayed in a frame on the specified origin.
XFrameOptions string `env:"X_FRAME_OPTIONS" json:"xFrameOptions,omitempty" yaml:"xFrameOptions,omitempty"`
// HSTSMaxAge sets the `Strict-Transport-Security` header to indicate how
// long (in seconds) browsers should remember that this site is only to
// be accessed using HTTPS. This reduces your exposure to some SSL-stripping
// man-in-the-middle (MITM) attacks.
// Optional. Default value 0.
HSTSMaxAge int `env:"HSTS_MAX_AGE" json:"hstsMaxAge,omitempty" yaml:"hstsMaxAge,omitempty"`
// HSTSExcludeSubdomains won't include subdomains tag in the `Strict Transport Security`
// header, excluding all subdomains from security policy. It has no effect
// unless HSTSMaxAge is set to a non-zero value.
// Optional. Default value false.
HSTSExcludeSubdomains bool `env:"HSTS_EXCLUDE_SUBDOMAINS" json:"hstsExcludeSubdomains,omitempty" yaml:"hstsExcludeSubdomains,omitempty"`
// ContentSecurityPolicy sets the `Content-Security-Policy` header providing
// security against cross-site scripting (XSS), clickjacking and other code
// injection attacks resulting from execution of malicious content in the
// trusted web page context.
// Optional. Default value "".
ContentSecurityPolicy string `env:"CONTENT_SECURITY_POLICY" json:"contentSecurityPolicy,omitempty" yaml:"contentSecurityPolicy,omitempty"`
// CSPReportOnly would use the `Content-Security-Policy-Report-Only` header instead
// of the `Content-Security-Policy` header. This allows iterative updates of the
// content security policy by only reporting the violations that would
// have occurred instead of blocking the resource.
// Optional. Default value false.
CSPReportOnly bool `env:"CSP_REPORT_ONLY" json:"cspReportOnly,omitempty" yaml:"cspReportOnly,omitempty"`
// HSTSPreloadEnabled will add the preload tag in the `Strict Transport Security`
// header, which enables the domain to be included in the HSTS preload list
// maintained by Chrome (and used by Firefox and Safari): https://hstspreload.org/
// Optional. Default value false.
HSTSPreloadEnabled bool `env:"HSTS_PRELOAD_ENABLED" json:"hstsPreloadEnabled,omitempty" yaml:"hstsPreloadEnabled,omitempty"`
// ReferrerPolicy sets the `Referrer-Policy` header providing security against
// leaking potentially sensitive request paths to third parties.
// Optional. Default value "".
ReferrerPolicy string `env:"REFERRER_POLICY" json:"referrerPolicy,omitempty" yaml:"referrerPolicy,omitempty"`
}
type Skipper ¶
func ChainSkipper ¶
func EqualPathSkipper ¶
func ExpressionSkipper ¶
ExpressionSkipper creates a Skipper function that evaluates expressions against an environment generated from requests.
Documentation can be found here: https://expr-lang.org/
func PrefixPathSkipper ¶
func SuffixPathSkipper ¶
type ValueExtractorError ¶
type ValueExtractorError struct {
// contains filtered or unexported fields
}
ValueExtractorError is error type when middleware extractor is unable to extract value from lookups
func (*ValueExtractorError) Error ¶
func (e *ValueExtractorError) Error() string
Error returns errors text
type ValuesExtractor ¶
type ValuesExtractor func(r *http.Request) ([]string, ExtractorSource, error)
ValuesExtractor defines a function for extracting values (keys/tokens) from the given context.
func CreateExtractors ¶
func CreateExtractors(lookups string, limit uint) ([]ValuesExtractor, error)
CreateExtractors creates ValuesExtractors from given lookups. lookups is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used to extract key from the request. Possible values:
- "header:<name>" or "header:<name>:<cut-prefix>" `<cut-prefix>` is argument value to cut/trim prefix of the extracted value. This is useful if header value has static prefix like `Authorization: <auth-scheme> <authorisation-parameters>` where part that we want to cut is `<auth-scheme> ` note the space at the end. In case of basic authentication `Authorization: Basic <credentials>` prefix we want to remove is `Basic `.
- "query:<name>"
- "param:<name>"
- "form:<name>"
- "cookie:<name>"
Multiple sources example: - "header:Authorization,header:X-Api-Key"
limit sets the maximum amount how many lookups can be returned.