diff --git a/conf/defaults.ini b/conf/defaults.ini index 1c114e17cbf..5f1455552aa 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -179,6 +179,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 a20b326c5b3..33381332b42 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -175,6 +175,30 @@ log_queries = # 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 6e249a7130e..122e0fe31c7 100644 --- a/docs/sources/installation/configuration.md +++ b/docs/sources/installation/configuration.md @@ -320,6 +320,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 f4f60c01559..2111a063b7d 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -1,6 +1,7 @@ package middleware import ( + "fmt" "net/http" "net/url" "strconv" @@ -241,10 +242,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 788ea7677c9..78954613007 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -86,14 +86,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 @@ -693,6 +699,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", "")