secure

package module
v2.1.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2018 License: MIT Imports: 9 Imported by: 1

README

Go Report Card Build Status Coverage

Security Headers

HTTP middleware for Go providing various security headers. It's 100% compatible with net/http package and various other routers. Requires a minimum of Go 1.7

Usage

Dynamic Content Security Policy

Headers like Strict Transport Policy seldom change but Content Security Policy's nonce directive needs to be randomized for every request. In addition to this, same nonce value must also be on html tags

<script nonce="2hgoUhs/="> ... </script>

Hence it is more practical to perform this at this level than in a reverse proxy. Due to this Content Security Policy Header or CSP has been separated from other security headers.

func main() {
    mux := http.NewServeMux()

    csp := &secure.CSP{
        Value:      `object-src 'none'; script-src {{nonce}} 'strict-dynamic'; base-uri 'self'; report-uri https://example.com/_csp;`,
        ByteAmount: 8,
    }

    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Base64 nonce: %s", secure.Nonce(r.Context())) // secure.Nonce(context.Context) returns Nonce associated with the present request Object
    })

    http.ListenAndServe(":8080", csp.Middleware()(mux))
}
Static Headers

Headers that are better off implemented in a Reverse Proxy, such as Ngnix, in case of one.

// main.go
func main() {
    mux := http.NewServeMux()

    s := &secure.Secure{
        STSIncludeSubdomains: true,
        STSPreload:           true,
        STSMaxAgeSeconds:     90,

        FrameOption: secure.FrameAllowFrom,
        FrameOrigin: "https://example.com/",

        ContentTypeNoSniff: true,

        XSSFilterBlock: true,

        HPKPPins: []string{
            "HBkhsug765gdKHhvdj6jdb7jJh/j+soZS7sWs=",
            "hjshHSHU68hbdkHhvdkgksgsg+jd/jHJ68HBH=",
        },
        HPKPMaxAge:            5184000,
        HPKPReportURI:         "https://www.example.org/hpkp-report",
        HPKPIncludeSubdomains: true,

        ExpectCTMaxAge:    5184000,
        ExpectCTEnforce:   true,
        ExpectCTReportUri: "https://www.example.org/ct-report",

        ReferrerPolicy: secure.ReferrerStrictOriginWhenCrossOrigin,
    }

    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Ok with Security Headers")
    })

    http.ListenAndServe(":8080", s.Middleware()(mux))
}
Configuration options

For various configuration options and other integration examples please refer the godoc.

Documentation

Overview

Example (Chi)

Sample showing integration with the awesome router go-chi

mux := chi.NewMux()

s := &secure.Secure{
	ContentTypeNoSniff: true,
}

mux.Use(s.Middleware())

mux.Get("/", func(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Ok with Headers")
})

http.ListenAndServe(":8080", mux)
Output:

Example (NetHttp)

Sample showing integration with the net/http

mux := http.NewServeMux()

s := &secure.Secure{
	ContentTypeNoSniff: true,
}

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Ok with Headers")
})

http.ListenAndServe(":8080", s.Middleware()(mux))
Output:

Index

Examples

Constants

View Source
const (
	// FrameSameOrigin is the SAMEORIGIN XFrameOption
	FrameSameOrigin frameOption = "SAMEORIGIN"
	// FrameDeny is the DENY XFrameOption
	FrameDeny frameOption = "DENY"
	// FrameAllowFrom is the DENY XFrameOption, if this is set then the XFrameOrigin must also be set
	FrameAllowFrom frameOption = "ALLOW-FROM"
)
View Source
const (
	// ReferrerNoReferrer will lead to the omiision of referrer information entirely.
	// No referrer information is sent along with requests.
	ReferrerNoReferrer referrerPolicy = "no-referrer"

	// ReferrerNoReferrerWhenDowngrade is the user agent's default behavior if no policy is specified.
	// The origin is sent as referrer to a-priori as-much-secure destination (HTTPS->HTTPS),
	// but isn't sent to a less secure destination (HTTPS->HTTP)
	ReferrerNoReferrerWhenDowngrade referrerPolicy = "no-referrer-when-downgrade"

	// ReferrerOrigin only sends the origin of the document as the referrer in all cases.
	// The document https://example.com/page.html will send the referrer https://example.com/.
	ReferrerOrigin referrerPolicy = "origin"

	// ReferrerOriginWhenCrossOrigin sends a full URL when performing a same-origin request,
	// but only sends the origin of the document for other cases.
	ReferrerOriginWhenCrossOrigin referrerPolicy = "origin-when-cross-origin"

	// ReferrerSameOrigin will send a referrer to same-site origins,
	// but cross-origin requests will contain no referrer information.
	ReferrerSameOrigin referrerPolicy = "same-origin"

	// ReferrerStrictOrigin only sends the origin of the document as the referrer to a-priori as-much-secure destination (HTTPS->HTTPS),
	// but won't send it to a less secure destination (HTTPS->HTTP).
	ReferrerStrictOrigin referrerPolicy = "strict-origin"

	// ReferrerStrictOriginWhenCrossOrigin sends a full URL when performing a same-origin request,
	// only sends the origin of the document to a-priori as-much-secure destination (HTTPS->HTTPS),
	// and sends no header to a less secure destination (HTTPS->HTTP).
	ReferrerStrictOriginWhenCrossOrigin referrerPolicy = "strict-origin-when-cross-origin"

	// ReferrerUnsafeURL sends a full URL when performing a same-origin or cross-origin request.
	// NOTE: This policy will leak origins and paths from TLS-protected resources to insecure origins.
	// Carefully consider the impact of this setting.
	ReferrerUnsafeURL referrerPolicy = "unsafe-url"
)
View Source
const NonceToken = "{{nonce}}"

NonceToken is the string token that gets replaced by the middleware with a dynamic nonce directive

Variables

This section is empty.

Functions

func Nonce

func Nonce(c context.Context) string

Nonce returns the nonce value present in the context. If no nonce is present it returns an empty string.

func RandNonce added in v1.1.0

func RandNonce(w io.ByteWriter, b int)

RandNonce writes the randomly generated nonce of length 'b' to the provided ByteWriter. Typical usecase would be to use this method to create own handlers/middlewares for packages that don't support net/http. Note: To get the nonce associated with the present request use `Nonce(context.Context)` method.

Types

type CSP

type CSP struct {
	// Value is the CSP header value.Eg: script-src {{nonce}} 'strict-dynamic'; object-src 'none';
	// If the Value contains '{{nonce}}', it will be replaced by a dynamic nonce {{nonce}} -> 'nonce-jagflah+==' every request.
	//
	// Generated nonce can be obtained using the `Nonce(context.Context)` function.
	Value string

	// ByteSize is the size of the nonce being generated in bytes. If passed <= '0' it will chnage to 16.
	// Default is 16.
	ByteSize int

	// ReportOnly will send report only header (Content-Security-Policy-Report-Only) instead of the regular header (Content-Security-Policy-Report-Only).
	// Enabling this option will result in browsers only reporting violation. Report-URI must be set along with this. Default is false.
	// Note: Package will not check for report-uri
	ReportOnly bool
}

CSP is used to configure the Content Security Policy Middleware. For more about csp please refer the mozilla docs.

func (*CSP) Middleware

func (c *CSP) Middleware() func(http.Handler) http.Handler

Middleware return a fuction that adds the configured csp headers, stores the nonce in th request context if configures, and passes the request to the next handler

Example
mux := http.NewServeMux()

csp := &secure.CSP{
	Value:    `object-src 'none'; script-src {{nonce}} 'strict-dynamic'; base-uri 'self'; report-uri https://appointy.com/_csp;`,
	ByteSize: 8,
}

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Base64 nonce: %s", secure.Nonce(r.Context()))
})

http.ListenAndServe(":8080", csp.Middleware()(mux))
Output:

type Secure

type Secure struct {
	STSMaxAgeSeconds     uint64
	STSIncludeSubdomains bool
	STSPreload           bool

	FrameOption frameOption
	FrameOrigin string

	ContentTypeNoSniff bool

	XSSFilterBlock bool

	HPKPPins              []string
	HPKPReportOnly        bool
	HPKPMaxAge            uint64
	HPKPIncludeSubdomains bool
	HPKPReportURI         string

	ExpectCTMaxAge    int
	ExpectCTEnforce   bool
	ExpectCTReportUri string

	ReferrerPolicy referrerPolicy
}

Secure is the middleware containing the configuration for the setup of various security headers

func (*Secure) Middleware

func (s *Secure) Middleware() func(http.Handler) http.Handler

Middleware returns a function that takes a http.Middleware returns a http.Middleware

Example
mux := http.NewServeMux()

s := &secure.Secure{
	ContentTypeNoSniff: true,
}

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Ok with Headers")
})

http.ListenAndServe(":8080", s.Middleware()(mux))
Output:

Jump to

Keyboard shortcuts

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