mirror of
https://github.com/jakejarvis/npqueue.git
synced 2026-07-26 08:26:03 -04:00
gin secure middleware
This commit is contained in:
Generated
+4
@@ -6,6 +6,10 @@
|
|||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
"Deps": [
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/gin-contrib/secure",
|
||||||
|
"Rev": "312887ea6e1f6d9b6dcb5fdd548f8c8dfb62eaca"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gin-contrib/sse",
|
"ImportPath": "github.com/gin-contrib/sse",
|
||||||
"Comment": "v0.1.0",
|
"Comment": "v0.1.0",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/contrib/static"
|
"github.com/gin-gonic/contrib/static"
|
||||||
|
"github.com/gin-contrib/secure"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
_ "github.com/heroku/x/hmetrics/onload"
|
_ "github.com/heroku/x/hmetrics/onload"
|
||||||
)
|
)
|
||||||
@@ -206,6 +207,17 @@ func main() {
|
|||||||
port := ":" + os.Getenv("PORT")
|
port := ":" + os.Getenv("PORT")
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
|
|
||||||
|
router.Use(secure.New(secure.Config{
|
||||||
|
SSLRedirect: true,
|
||||||
|
SSLHost: "np.pogge.rs",
|
||||||
|
STSSeconds: 315360000,
|
||||||
|
STSIncludeSubdomains: false,
|
||||||
|
FrameDeny: true,
|
||||||
|
ContentTypeNosniff: true,
|
||||||
|
BrowserXssFilter: true,
|
||||||
|
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
|
||||||
|
}))
|
||||||
|
|
||||||
// Serve frontend static files
|
// Serve frontend static files
|
||||||
router.Use(static.Serve("/", static.LocalFile("./public", true)))
|
router.Use(static.Serve("/", static.LocalFile("./public", true)))
|
||||||
|
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
coverage.out
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
language: go
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.8.x
|
||||||
|
- 1.9.x
|
||||||
|
- 1.10.x
|
||||||
|
- 1.11.x
|
||||||
|
- 1.12.x
|
||||||
|
- master
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
include:
|
||||||
|
- go: 1.11.x
|
||||||
|
env: GO111MODULE=on
|
||||||
|
- go: 1.12.x
|
||||||
|
env: GO111MODULE=on
|
||||||
|
|
||||||
|
install:
|
||||||
|
- go get -d -t -v
|
||||||
|
- go get github.com/campoy/embedmd
|
||||||
|
|
||||||
|
script:
|
||||||
|
- embedmd -d *.md
|
||||||
|
- go test -v -covermode=atomic -coverprofile=coverage.out .
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
webhooks:
|
||||||
|
urls:
|
||||||
|
- https://webhooks.gitter.im/e/acc2c57482e94b44f557
|
||||||
|
on_success: change
|
||||||
|
on_failure: always
|
||||||
|
on_start: false
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 gin-contrib
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
# Secure
|
||||||
|
|
||||||
|
[](https://travis-ci.org/gin-contrib/secure)
|
||||||
|
[](https://codecov.io/gh/gin-contrib/secure)
|
||||||
|
[](https://goreportcard.com/report/github.com/gin-contrib/secure)
|
||||||
|
[](https://godoc.org/github.com/gin-contrib/secure)
|
||||||
|
|
||||||
|
Secure meddleware for [Gin](https://github.com/gin-gonic/gin/) framework.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
See the [example1](example/code1/example.go), [example2](example/code2/example.go).
|
||||||
|
|
||||||
|
DefaultConfig returns a Configuration with strict security settings
|
||||||
|
|
||||||
|
[embedmd]:# (secure.go go /func DefaultConfig/ /^}$/)
|
||||||
|
```go
|
||||||
|
func DefaultConfig() Config {
|
||||||
|
return Config{
|
||||||
|
SSLRedirect: true,
|
||||||
|
IsDevelopment: false,
|
||||||
|
STSSeconds: 315360000,
|
||||||
|
STSIncludeSubdomains: true,
|
||||||
|
FrameDeny: true,
|
||||||
|
ContentTypeNosniff: true,
|
||||||
|
BrowserXssFilter: true,
|
||||||
|
ContentSecurityPolicy: "default-src 'self'",
|
||||||
|
IENoOpen: true,
|
||||||
|
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[embedmd]:# (example/code1/example.go go)
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-contrib/secure"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
router := gin.Default()
|
||||||
|
|
||||||
|
router.Use(secure.New(secure.Config{
|
||||||
|
AllowedHosts: []string{"example.com", "ssl.example.com"},
|
||||||
|
SSLRedirect: true,
|
||||||
|
SSLHost: "ssl.example.com",
|
||||||
|
STSSeconds: 315360000,
|
||||||
|
STSIncludeSubdomains: true,
|
||||||
|
FrameDeny: true,
|
||||||
|
ContentTypeNosniff: true,
|
||||||
|
BrowserXssFilter: true,
|
||||||
|
ContentSecurityPolicy: "default-src 'self'",
|
||||||
|
IENoOpen: true,
|
||||||
|
ReferrerPolicy: "strict-origin-when-cross-origin",
|
||||||
|
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
|
||||||
|
}))
|
||||||
|
|
||||||
|
router.GET("/ping", func(c *gin.Context) {
|
||||||
|
c.String(200, "pong")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Listen and Server in 0.0.0.0:8080
|
||||||
|
router.Run()
|
||||||
|
}
|
||||||
|
```
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
module github.com/gin-contrib/secure
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/gin-gonic/gin v1.4.0
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
)
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
|
||||||
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||||
|
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
|
||||||
|
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||||
|
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||||
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
|
||||||
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
||||||
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||||
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
|
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||||
|
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
+184
@@ -0,0 +1,184 @@
|
|||||||
|
package secure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// Secure is a middleware that helps setup a few basic security features. A single secure.Options struct can be
|
||||||
|
// provided to configure which features should be enabled, and the ability to override a few of the default values.
|
||||||
|
policy struct {
|
||||||
|
// Customize Secure with an Options struct.
|
||||||
|
config Config
|
||||||
|
fixedHeaders []header
|
||||||
|
}
|
||||||
|
|
||||||
|
header struct {
|
||||||
|
key string
|
||||||
|
value []string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constructs a new Policy instance with supplied options.
|
||||||
|
func newPolicy(config Config) *policy {
|
||||||
|
policy := &policy{}
|
||||||
|
policy.loadConfig(config)
|
||||||
|
return policy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policy) loadConfig(config Config) {
|
||||||
|
p.config = config
|
||||||
|
p.fixedHeaders = make([]header, 0, 5)
|
||||||
|
|
||||||
|
// Frame Options header.
|
||||||
|
if len(config.CustomFrameOptionsValue) > 0 {
|
||||||
|
p.addHeader("X-Frame-Options", config.CustomFrameOptionsValue)
|
||||||
|
} else if config.FrameDeny {
|
||||||
|
p.addHeader("X-Frame-Options", "DENY")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content Type Options header.
|
||||||
|
if config.ContentTypeNosniff {
|
||||||
|
p.addHeader("X-Content-Type-Options", "nosniff")
|
||||||
|
}
|
||||||
|
|
||||||
|
// XSS Protection header.
|
||||||
|
if config.BrowserXssFilter {
|
||||||
|
p.addHeader("X-Xss-Protection", "1; mode=block")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content Security Policy header.
|
||||||
|
if len(config.ContentSecurityPolicy) > 0 {
|
||||||
|
p.addHeader("Content-Security-Policy", config.ContentSecurityPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(config.ReferrerPolicy) > 0 {
|
||||||
|
p.addHeader("Referrer-Policy", config.ReferrerPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strict Transport Security header.
|
||||||
|
if config.STSSeconds != 0 {
|
||||||
|
stsSub := ""
|
||||||
|
if config.STSIncludeSubdomains {
|
||||||
|
stsSub = "; includeSubdomains"
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// "max-age=%d%s" refactor
|
||||||
|
p.addHeader(
|
||||||
|
"Strict-Transport-Security",
|
||||||
|
fmt.Sprintf("max-age=%d%s", config.STSSeconds, stsSub))
|
||||||
|
}
|
||||||
|
|
||||||
|
// X-Download-Options header.
|
||||||
|
if config.IENoOpen {
|
||||||
|
p.addHeader("X-Download-Options", "noopen")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policy) addHeader(key string, value string) {
|
||||||
|
p.fixedHeaders = append(p.fixedHeaders, header{
|
||||||
|
key: key,
|
||||||
|
value: []string{value},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policy) applyToContext(c *gin.Context) bool {
|
||||||
|
if !p.config.IsDevelopment {
|
||||||
|
p.writeSecureHeaders(c)
|
||||||
|
|
||||||
|
if !p.checkAllowHosts(c) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !p.checkSSL(c) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policy) writeSecureHeaders(c *gin.Context) {
|
||||||
|
header := c.Writer.Header()
|
||||||
|
for _, pair := range p.fixedHeaders {
|
||||||
|
header[pair.key] = pair.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policy) checkAllowHosts(c *gin.Context) bool {
|
||||||
|
if len(p.config.AllowedHosts) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
host := c.Request.Host
|
||||||
|
if len(host) == 0 {
|
||||||
|
host = c.Request.URL.Host
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, allowedHost := range p.config.AllowedHosts {
|
||||||
|
if strings.EqualFold(allowedHost, host) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.config.BadHostHandler != nil {
|
||||||
|
p.config.BadHostHandler(c)
|
||||||
|
} else {
|
||||||
|
c.AbortWithStatus(403)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policy) isSSLRequest(req *http.Request) bool {
|
||||||
|
if strings.EqualFold(req.URL.Scheme, "https") || req.TLS != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for h, v := range p.config.SSLProxyHeaders {
|
||||||
|
hv, ok := req.Header[h]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.EqualFold(hv[0], v) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policy) checkSSL(c *gin.Context) bool {
|
||||||
|
if !p.config.SSLRedirect {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
req := c.Request
|
||||||
|
isSSLRequest := p.isSSLRequest(req)
|
||||||
|
if isSSLRequest {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// req.Host vs req.URL.Host
|
||||||
|
url := req.URL
|
||||||
|
url.Scheme = "https"
|
||||||
|
url.Host = req.Host
|
||||||
|
|
||||||
|
if len(p.config.SSLHost) > 0 {
|
||||||
|
url.Host = p.config.SSLHost
|
||||||
|
}
|
||||||
|
|
||||||
|
status := http.StatusMovedPermanently
|
||||||
|
if p.config.SSLTemporaryRedirect {
|
||||||
|
status = http.StatusTemporaryRedirect
|
||||||
|
}
|
||||||
|
c.Redirect(status, url.String())
|
||||||
|
c.Abort()
|
||||||
|
return false
|
||||||
|
}
|
||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
package secure
|
||||||
|
|
||||||
|
import "github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
// Config is a struct for specifying configuration options for the secure.
|
||||||
|
type Config struct {
|
||||||
|
// AllowedHosts is a list of fully qualified domain names that are allowed.
|
||||||
|
//Default is empty list, which allows any and all host names.
|
||||||
|
AllowedHosts []string
|
||||||
|
// If SSLRedirect is set to true, then only allow https requests.
|
||||||
|
// Default is false.
|
||||||
|
SSLRedirect bool
|
||||||
|
// If SSLTemporaryRedirect is true, the a 302 will be used while redirecting.
|
||||||
|
// Default is false (301).
|
||||||
|
SSLTemporaryRedirect bool
|
||||||
|
// SSLHost is the host name that is used to redirect http requests to https.
|
||||||
|
// Default is "", which indicates to use the same host.
|
||||||
|
SSLHost string
|
||||||
|
// STSSeconds is the max-age of the Strict-Transport-Security header.
|
||||||
|
// Default is 0, which would NOT include the header.
|
||||||
|
STSSeconds int64
|
||||||
|
// If STSIncludeSubdomains is set to true, the `includeSubdomains` will
|
||||||
|
// be appended to the Strict-Transport-Security header. Default is false.
|
||||||
|
STSIncludeSubdomains bool
|
||||||
|
// If FrameDeny is set to true, adds the X-Frame-Options header with
|
||||||
|
// the value of `DENY`. Default is false.
|
||||||
|
FrameDeny bool
|
||||||
|
// CustomFrameOptionsValue allows the X-Frame-Options header value
|
||||||
|
// to be set with a custom value. This overrides the FrameDeny option.
|
||||||
|
CustomFrameOptionsValue string
|
||||||
|
// If ContentTypeNosniff is true, adds the X-Content-Type-Options header
|
||||||
|
// with the value `nosniff`. Default is false.
|
||||||
|
ContentTypeNosniff bool
|
||||||
|
// If BrowserXssFilter is true, adds the X-XSS-Protection header with
|
||||||
|
// the value `1; mode=block`. Default is false.
|
||||||
|
BrowserXssFilter bool
|
||||||
|
// ContentSecurityPolicy allows the Content-Security-Policy header value
|
||||||
|
// to be set with a custom value. Default is "".
|
||||||
|
ContentSecurityPolicy string
|
||||||
|
// HTTP header "Referrer-Policy" governs which referrer information, sent in the Referrer header, should be included with requests made.
|
||||||
|
ReferrerPolicy string
|
||||||
|
// When true, the whole secury policy applied by the middleware is disable
|
||||||
|
// completely.
|
||||||
|
IsDevelopment bool
|
||||||
|
// Handlers for when an error occurs (ie bad host).
|
||||||
|
BadHostHandler gin.HandlerFunc
|
||||||
|
// Prevent Internet Explorer from executing downloads in your site’s context
|
||||||
|
IENoOpen bool
|
||||||
|
|
||||||
|
// If the request is insecure, treat it as secure if any of the headers in this dict are set to their corresponding value
|
||||||
|
// This is useful when your app is running behind a secure proxy that forwards requests to your app over http (such as on Heroku).
|
||||||
|
SSLProxyHeaders map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultConfig returns a Configuration with strict security settings.
|
||||||
|
// ```
|
||||||
|
// SSLRedirect: true
|
||||||
|
// IsDevelopment: false
|
||||||
|
// STSSeconds: 315360000
|
||||||
|
// STSIncludeSubdomains: true
|
||||||
|
// FrameDeny: true
|
||||||
|
// ContentTypeNosniff: true
|
||||||
|
// BrowserXssFilter: true
|
||||||
|
// ContentSecurityPolicy: "default-src 'self'"
|
||||||
|
// SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
|
||||||
|
// ```
|
||||||
|
func DefaultConfig() Config {
|
||||||
|
return Config{
|
||||||
|
SSLRedirect: true,
|
||||||
|
IsDevelopment: false,
|
||||||
|
STSSeconds: 315360000,
|
||||||
|
STSIncludeSubdomains: true,
|
||||||
|
FrameDeny: true,
|
||||||
|
ContentTypeNosniff: true,
|
||||||
|
BrowserXssFilter: true,
|
||||||
|
ContentSecurityPolicy: "default-src 'self'",
|
||||||
|
IENoOpen: true,
|
||||||
|
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates an instance of the secure middleware using the specified configuration.
|
||||||
|
// router.Use(secure.N)
|
||||||
|
func New(config Config) gin.HandlerFunc {
|
||||||
|
policy := newPolicy(config)
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
if !policy.applyToContext(c) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user