mirror of
https://github.com/labstack/echo.git
synced 2024-12-24 20:14:31 +02:00
feat(secure): support Content-Security-Policy-Report-Only header (#1287)
Closes #1283
This commit is contained in:
parent
17b5044459
commit
802fb5bba6
13
echo.go
13
echo.go
@ -212,12 +212,13 @@ const (
|
|||||||
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
|
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
|
||||||
|
|
||||||
// Security
|
// Security
|
||||||
HeaderStrictTransportSecurity = "Strict-Transport-Security"
|
HeaderStrictTransportSecurity = "Strict-Transport-Security"
|
||||||
HeaderXContentTypeOptions = "X-Content-Type-Options"
|
HeaderXContentTypeOptions = "X-Content-Type-Options"
|
||||||
HeaderXXSSProtection = "X-XSS-Protection"
|
HeaderXXSSProtection = "X-XSS-Protection"
|
||||||
HeaderXFrameOptions = "X-Frame-Options"
|
HeaderXFrameOptions = "X-Frame-Options"
|
||||||
HeaderContentSecurityPolicy = "Content-Security-Policy"
|
HeaderContentSecurityPolicy = "Content-Security-Policy"
|
||||||
HeaderXCSRFToken = "X-CSRF-Token"
|
HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
|
||||||
|
HeaderXCSRFToken = "X-CSRF-Token"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -53,6 +53,13 @@ type (
|
|||||||
// trusted web page context.
|
// trusted web page context.
|
||||||
// Optional. Default value "".
|
// Optional. Default value "".
|
||||||
ContentSecurityPolicy string `yaml:"content_security_policy"`
|
ContentSecurityPolicy string `yaml:"content_security_policy"`
|
||||||
|
|
||||||
|
// 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 `yaml:"csp_report_only"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -108,7 +115,11 @@ func SecureWithConfig(config SecureConfig) echo.MiddlewareFunc {
|
|||||||
res.Header().Set(echo.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", config.HSTSMaxAge, subdomains))
|
res.Header().Set(echo.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", config.HSTSMaxAge, subdomains))
|
||||||
}
|
}
|
||||||
if config.ContentSecurityPolicy != "" {
|
if config.ContentSecurityPolicy != "" {
|
||||||
res.Header().Set(echo.HeaderContentSecurityPolicy, config.ContentSecurityPolicy)
|
if config.CSPReportOnly {
|
||||||
|
res.Header().Set(echo.HeaderContentSecurityPolicyReportOnly, config.ContentSecurityPolicy)
|
||||||
|
} else {
|
||||||
|
res.Header().Set(echo.HeaderContentSecurityPolicy, config.ContentSecurityPolicy)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return next(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
|
@ -42,4 +42,24 @@ func TestSecure(t *testing.T) {
|
|||||||
assert.Equal(t, "", rec.Header().Get(echo.HeaderXFrameOptions))
|
assert.Equal(t, "", rec.Header().Get(echo.HeaderXFrameOptions))
|
||||||
assert.Equal(t, "max-age=3600; includeSubdomains", rec.Header().Get(echo.HeaderStrictTransportSecurity))
|
assert.Equal(t, "max-age=3600; includeSubdomains", rec.Header().Get(echo.HeaderStrictTransportSecurity))
|
||||||
assert.Equal(t, "default-src 'self'", rec.Header().Get(echo.HeaderContentSecurityPolicy))
|
assert.Equal(t, "default-src 'self'", rec.Header().Get(echo.HeaderContentSecurityPolicy))
|
||||||
|
assert.Equal(t, "", rec.Header().Get(echo.HeaderContentSecurityPolicyReportOnly))
|
||||||
|
|
||||||
|
// Custom with CSPReportOnly flag
|
||||||
|
req.Header.Set(echo.HeaderXForwardedProto, "https")
|
||||||
|
rec = httptest.NewRecorder()
|
||||||
|
c = e.NewContext(req, rec)
|
||||||
|
SecureWithConfig(SecureConfig{
|
||||||
|
XSSProtection: "",
|
||||||
|
ContentTypeNosniff: "",
|
||||||
|
XFrameOptions: "",
|
||||||
|
HSTSMaxAge: 3600,
|
||||||
|
ContentSecurityPolicy: "default-src 'self'",
|
||||||
|
CSPReportOnly: true,
|
||||||
|
})(h)(c)
|
||||||
|
assert.Equal(t, "", rec.Header().Get(echo.HeaderXXSSProtection))
|
||||||
|
assert.Equal(t, "", rec.Header().Get(echo.HeaderXContentTypeOptions))
|
||||||
|
assert.Equal(t, "", rec.Header().Get(echo.HeaderXFrameOptions))
|
||||||
|
assert.Equal(t, "max-age=3600; includeSubdomains", rec.Header().Get(echo.HeaderStrictTransportSecurity))
|
||||||
|
assert.Equal(t, "default-src 'self'", rec.Header().Get(echo.HeaderContentSecurityPolicyReportOnly))
|
||||||
|
assert.Equal(t, "", rec.Header().Get(echo.HeaderContentSecurityPolicy))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user