diff --git a/conf/defaults.ini b/conf/defaults.ini index 4b187d7e8be..af362157aea 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -182,6 +182,31 @@ cookie_samesite = lax # set to true if you want to allow browsers to render Grafana in a , , or . default is false. allow_embedding = false +# Set to true if you want to enable http strict transport security (HSTS) response header. +# This is only sent when HTTPS is enabled in this configuration. +# HSTS tells browsers that the site should only be accessed using HTTPS. +# The default will change to true in the next minor release, 6.3. +strict_transport_security = false + +# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled. +strict_transport_security_max_age_seconds = 86400 + +# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled. +strict_transport_security_preload = false + +# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled. +strict_transport_security_subdomains = false + +# Set to true to enable the X-Content-Type-Options response header. +# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised +# in the Content-Type headers should not be changed and be followed. The default will change to true in the next minor release, 6.3. +x_content_type_options = false + +# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading +# when they detect reflected cross-site scripting (XSS) attacks. The default will change to true in the next minor release, 6.3. +x_xss_protection = false + + #################################### Snapshots ########################### [snapshots] # snapshot sharing options diff --git a/conf/sample.ini b/conf/sample.ini index fb1635713b4..528becfbd09 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -178,6 +178,30 @@ # set to true if you want to allow browsers to render Grafana in a , , or . default is false. ;allow_embedding = false +# Set to true if you want to enable http strict transport security (HSTS) response header. +# This is only sent when HTTPS is enabled in this configuration. +# HSTS tells browsers that the site should only be accessed using HTTPS. +# The default version will change to true in the next minor release, 6.3. +;strict_transport_security = false + +# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled. +;strict_transport_security_max_age_seconds = 86400 + +# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled. +;strict_transport_security_preload = false + +# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled. +;strict_transport_security_subdomains = false + +# Set to true to enable the X-Content-Type-Options response header. +# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised +# in the Content-Type headers should not be changed and be followed. The default will change to true in the next minor release, 6.3. +;x_content_type_options = false + +# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading +# when they detect reflected cross-site scripting (XSS) attacks. The default will change to true in the next minor release, 6.3. +;x_xss_protection = false + #################################### Snapshots ########################### [snapshots] # snapshot sharing options diff --git a/docs/sources/installation/configuration.md b/docs/sources/installation/configuration.md index 357d23ca1a7..486d63a1e76 100644 --- a/docs/sources/installation/configuration.md +++ b/docs/sources/installation/configuration.md @@ -329,6 +329,30 @@ When `false`, the HTTP header `X-Frame-Options: deny` will be set in Grafana HTT browsers to not allow rendering Grafana in a ``, ``, `` or ``. The main goal is to mitigate the risk of [Clickjacking](https://www.owasp.org/index.php/Clickjacking). Default is `false`. +### strict_transport_security + +Set to `true` if you want to enable http `Strict-Transport-Security` (HSTS) response header. This is only sent when HTTPS is enabled in this configuration. HSTS tells browsers that the site should only be accessed using HTTPS. The default value is `false` until the next minor release, `6.3`. + +### strict_transport_security_max_age_seconds + +Sets how long a browser should cache HSTS in seconds. Only applied if strict_transport_security is enabled. The default value is `86400`. + +### strict_transport_security_preload + +Set to `true` if to enable HSTS `preloading` option. Only applied if strict_transport_security is enabled. The default value is `false`. + +### strict_transport_security_subdomains + +Set to `true` if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled. The default value is `false`. + +### x_content_type_options + +Set to `true` to enable the X-Content-Type-Options response header. The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed. The default value is `false` until the next minor release, `6.3`. + +### x_xss_protection + +Set to `false` to disable the X-XSS-Protection header, which tells browsers to stop pages from loading when they detect reflected cross-site scripting (XSS) attacks. The default value is `false` until the next minor release, `6.3`. + ## [users] diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go index 1b465e7a4e5..e28054fe250 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -1,6 +1,7 @@ package middleware import ( + "fmt" "net/http" "net/url" "strconv" @@ -242,10 +243,35 @@ func AddDefaultResponseHeaders() macaron.Handler { if !setting.AllowEmbedding { AddXFrameOptionsDenyHeader(w) } + + AddSecurityHeaders(w) }) } } +// AddSecurityHeaders adds various HTTP(S) response headers that enable various security protections behaviors in the client's browser. +func AddSecurityHeaders(w macaron.ResponseWriter) { + if setting.Protocol == setting.HTTPS && setting.StrictTransportSecurity { + strictHeader := "Strict-Transport-Security" + w.Header().Add(strictHeader, fmt.Sprintf("max-age=%v", setting.StrictTransportSecurityMaxAge)) + if setting.StrictTransportSecurityPreload { + w.Header().Add(strictHeader, "preload") + } + if setting.StrictTransportSecuritySubDomains { + w.Header().Add(strictHeader, "includeSubDomains") + } + } + + if setting.ContentTypeProtectionHeader { + w.Header().Add("X-Content-Type-Options", "nosniff") + } + + if setting.XSSProtectionHeader { + w.Header().Add("X-XSS-Protection", "1") + w.Header().Add("X-XSS-Protection", "mode=block") + } +} + func AddNoCacheHeaders(w macaron.ResponseWriter) { w.Header().Add("Cache-Control", "no-cache") w.Header().Add("Pragma", "no-cache") diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index eef813a3afe..05d42f1000e 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -87,14 +87,20 @@ var ( EnforceDomain bool // Security settings. - SecretKey string - DisableGravatar bool - EmailCodeValidMinutes int - DataProxyWhiteList map[string]bool - DisableBruteForceLoginProtection bool - CookieSecure bool - CookieSameSite http.SameSite - AllowEmbedding bool + SecretKey string + DisableGravatar bool + EmailCodeValidMinutes int + DataProxyWhiteList map[string]bool + DisableBruteForceLoginProtection bool + CookieSecure bool + CookieSameSite http.SameSite + AllowEmbedding bool + XSSProtectionHeader bool + ContentTypeProtectionHeader bool + StrictTransportSecurity bool + StrictTransportSecurityMaxAge int + StrictTransportSecurityPreload bool + StrictTransportSecuritySubDomains bool // Snapshots ExternalSnapshotUrl string @@ -698,6 +704,13 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error { AllowEmbedding = security.Key("allow_embedding").MustBool(false) + ContentTypeProtectionHeader = security.Key("x_content_type_options").MustBool(false) + XSSProtectionHeader = security.Key("x_xss_protection").MustBool(false) + StrictTransportSecurity = security.Key("strict_transport_security").MustBool(false) + StrictTransportSecurityMaxAge = security.Key("strict_transport_security_max_age_seconds").MustInt(86400) + StrictTransportSecurityPreload = security.Key("strict_transport_security_preload").MustBool(false) + StrictTransportSecuritySubDomains = security.Key("strict_transport_security_subdomains").MustBool(false) + // read snapshots settings snapshots := iniFile.Section("snapshots") ExternalSnapshotUrl, err = valueAsString(snapshots, "external_snapshot_url", "")