2014-10-05 22:50:04 +08:00
|
|
|
package middleware
|
|
|
|
|
|
|
|
import (
|
2019-06-12 19:15:50 +08:00
|
|
|
"fmt"
|
2019-05-06 15:22:59 +08:00
|
|
|
"strings"
|
2014-10-05 22:50:04 +08:00
|
|
|
|
2019-05-17 19:57:26 +08:00
|
|
|
macaron "gopkg.in/macaron.v1"
|
|
|
|
|
2019-06-26 14:47:03 +08:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2015-02-05 17:37:13 +08:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2019-08-02 17:16:31 +08:00
|
|
|
)
|
|
|
|
|
2018-10-11 18:36:04 +08:00
|
|
|
var (
|
2019-08-02 17:16:31 +08:00
|
|
|
ReqGrafanaAdmin = Auth(&AuthOptions{
|
|
|
|
ReqSignedIn: true,
|
|
|
|
ReqGrafanaAdmin: true,
|
|
|
|
})
|
|
|
|
ReqSignedIn = Auth(&AuthOptions{ReqSignedIn: true})
|
|
|
|
ReqEditorRole = RoleAuth(models.ROLE_EDITOR, models.ROLE_ADMIN)
|
|
|
|
ReqOrgAdmin = RoleAuth(models.ROLE_ADMIN)
|
2018-10-11 18:36:04 +08:00
|
|
|
)
|
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
func AddDefaultResponseHeaders(cfg *setting.Cfg) macaron.Handler {
|
2019-05-06 15:22:59 +08:00
|
|
|
return func(ctx *macaron.Context) {
|
|
|
|
ctx.Resp.Before(func(w macaron.ResponseWriter) {
|
2020-02-19 05:53:40 +08:00
|
|
|
// if response has already been written, skip.
|
|
|
|
if w.Written() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-05-06 15:22:59 +08:00
|
|
|
if !strings.HasPrefix(ctx.Req.URL.Path, "/api/datasources/proxy/") {
|
2020-12-11 18:44:44 +08:00
|
|
|
addNoCacheHeaders(ctx.Resp)
|
2019-05-06 15:22:59 +08:00
|
|
|
}
|
2019-05-06 15:56:23 +08:00
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
if !cfg.AllowEmbedding {
|
|
|
|
addXFrameOptionsDenyHeader(w)
|
2019-05-06 15:56:23 +08:00
|
|
|
}
|
2019-06-12 19:15:50 +08:00
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
addSecurityHeaders(w, cfg)
|
2019-05-06 15:22:59 +08:00
|
|
|
})
|
2017-07-04 22:33:37 +08:00
|
|
|
}
|
|
|
|
}
|
2019-05-06 15:22:59 +08:00
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
// addSecurityHeaders adds HTTP(S) response headers that enable various security protections in the client's browser.
|
|
|
|
func addSecurityHeaders(w macaron.ResponseWriter, cfg *setting.Cfg) {
|
|
|
|
if (cfg.Protocol == setting.HTTPSScheme || cfg.Protocol == setting.HTTP2Scheme) && cfg.StrictTransportSecurity {
|
|
|
|
strictHeaderValues := []string{fmt.Sprintf("max-age=%v", cfg.StrictTransportSecurityMaxAge)}
|
|
|
|
if cfg.StrictTransportSecurityPreload {
|
2019-06-19 02:24:23 +08:00
|
|
|
strictHeaderValues = append(strictHeaderValues, "preload")
|
2019-06-12 19:15:50 +08:00
|
|
|
}
|
2020-12-11 18:44:44 +08:00
|
|
|
if cfg.StrictTransportSecuritySubDomains {
|
2019-06-19 02:24:23 +08:00
|
|
|
strictHeaderValues = append(strictHeaderValues, "includeSubDomains")
|
2019-06-12 19:15:50 +08:00
|
|
|
}
|
2019-06-19 02:24:23 +08:00
|
|
|
w.Header().Add("Strict-Transport-Security", strings.Join(strictHeaderValues, "; "))
|
2019-06-12 19:15:50 +08:00
|
|
|
}
|
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
if cfg.ContentTypeProtectionHeader {
|
2019-06-12 19:15:50 +08:00
|
|
|
w.Header().Add("X-Content-Type-Options", "nosniff")
|
|
|
|
}
|
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
if cfg.XSSProtectionHeader {
|
2019-06-18 05:46:35 +08:00
|
|
|
w.Header().Add("X-XSS-Protection", "1; mode=block")
|
2019-06-12 19:15:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
func addNoCacheHeaders(w macaron.ResponseWriter) {
|
2019-05-06 15:22:59 +08:00
|
|
|
w.Header().Add("Cache-Control", "no-cache")
|
|
|
|
w.Header().Add("Pragma", "no-cache")
|
|
|
|
w.Header().Add("Expires", "-1")
|
|
|
|
}
|
2019-05-06 15:56:23 +08:00
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
func addXFrameOptionsDenyHeader(w macaron.ResponseWriter) {
|
2019-05-06 15:56:23 +08:00
|
|
|
w.Header().Add("X-Frame-Options", "deny")
|
|
|
|
}
|