mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 15:42:13 +08:00
Enforce domain, host header validation against domain setting, Refactoring of PR #1866, Closes #1732
This commit is contained in:
@ -29,6 +29,10 @@ http_port = 3000
|
|||||||
# The public facing domain name used to access grafana from a browser
|
# The public facing domain name used to access grafana from a browser
|
||||||
domain = localhost
|
domain = localhost
|
||||||
|
|
||||||
|
# Redirect to correct domain if host header does not match domain
|
||||||
|
# Prevents DNS rebinding attacks
|
||||||
|
enforce_domain = false
|
||||||
|
|
||||||
# The full public facing url
|
# The full public facing url
|
||||||
root_url = %(protocol)s://%(domain)s:%(http_port)s/
|
root_url = %(protocol)s://%(domain)s:%(http_port)s/
|
||||||
|
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
# The public facing domain name used to access grafana from a browser
|
# The public facing domain name used to access grafana from a browser
|
||||||
;domain = localhost
|
;domain = localhost
|
||||||
|
|
||||||
|
# Redirect to correct domain if host header does not match domain
|
||||||
|
# Prevents DNS rebinding attacks
|
||||||
|
;enforce_domain = false
|
||||||
|
|
||||||
# The full public facing url
|
# The full public facing url
|
||||||
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
|
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
|
||||||
|
|
||||||
|
@ -72,6 +72,9 @@ Another way is put nginx or apache infront of Grafana and have them proxy reques
|
|||||||
This setting is only used in as a part of the root_url setting (see below). Important if you
|
This setting is only used in as a part of the root_url setting (see below). Important if you
|
||||||
use github or google oauth.
|
use github or google oauth.
|
||||||
|
|
||||||
|
### enforce_domain
|
||||||
|
Redirect to correct domain if host header does not match domain. Prevents DNS rebinding attacks. Default is false.
|
||||||
|
|
||||||
### root_url
|
### root_url
|
||||||
This is the full url used to access grafana from a web browser. This is important if you use
|
This is the full url used to access grafana from a web browser. This is important if you use
|
||||||
google or github oauth authentication (for the callback url to be correct).
|
google or github oauth authentication (for the callback url to be correct).
|
||||||
|
@ -40,6 +40,10 @@ func newMacaron() *macaron.Macaron {
|
|||||||
Delims: macaron.Delims{Left: "[[", Right: "]]"},
|
Delims: macaron.Delims{Left: "[[", Right: "]]"},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
if setting.EnforceDomain {
|
||||||
|
m.Use(middleware.ValidateHostHeader(setting.Domain))
|
||||||
|
}
|
||||||
|
|
||||||
m.Use(middleware.GetContextHandler())
|
m.Use(middleware.GetContextHandler())
|
||||||
m.Use(middleware.Sessioner(&setting.SessionOptions))
|
m.Use(middleware.Sessioner(&setting.SessionOptions))
|
||||||
|
|
||||||
|
@ -34,16 +34,6 @@ func GetContextHandler() macaron.Handler {
|
|||||||
AllowAnonymous: false,
|
AllowAnonymous: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
h := ctx.Req.Host
|
|
||||||
if i := strings.Index(h, ":"); i >= 0 {
|
|
||||||
h = h[:i]
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.EqualFold(h, setting.Domain) {
|
|
||||||
ctx.Redirect(strings.TrimSuffix(setting.AppUrl, "/")+ctx.Req.RequestURI, 301)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// the order in which these are tested are important
|
// the order in which these are tested are important
|
||||||
// look for api key in Authorization header first
|
// look for api key in Authorization header first
|
||||||
// then init session and look for userId in session
|
// then init session and look for userId in session
|
||||||
|
22
pkg/middleware/validate_host.go
Normal file
22
pkg/middleware/validate_host.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Unknwon/macaron"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidateHostHeader(domain string) macaron.Handler {
|
||||||
|
return func(c *macaron.Context) {
|
||||||
|
h := c.Req.Host
|
||||||
|
if i := strings.Index(h, ":"); i >= 0 {
|
||||||
|
h = h[:i]
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.EqualFold(h, domain) {
|
||||||
|
c.Redirect(strings.TrimSuffix(setting.AppUrl, "/")+c.Req.RequestURI, 301)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -65,6 +65,7 @@ var (
|
|||||||
RouterLogging bool
|
RouterLogging bool
|
||||||
StaticRootPath string
|
StaticRootPath string
|
||||||
EnableGzip bool
|
EnableGzip bool
|
||||||
|
EnforceDomain bool
|
||||||
|
|
||||||
// Security settings.
|
// Security settings.
|
||||||
SecretKey string
|
SecretKey string
|
||||||
@ -355,10 +356,10 @@ func NewConfigContext(args *CommandLineArgs) {
|
|||||||
Domain = server.Key("domain").MustString("localhost")
|
Domain = server.Key("domain").MustString("localhost")
|
||||||
HttpAddr = server.Key("http_addr").MustString("0.0.0.0")
|
HttpAddr = server.Key("http_addr").MustString("0.0.0.0")
|
||||||
HttpPort = server.Key("http_port").MustString("3000")
|
HttpPort = server.Key("http_port").MustString("3000")
|
||||||
|
|
||||||
StaticRootPath = makeAbsolute(server.Key("static_root_path").String(), HomePath)
|
StaticRootPath = makeAbsolute(server.Key("static_root_path").String(), HomePath)
|
||||||
RouterLogging = server.Key("router_logging").MustBool(false)
|
RouterLogging = server.Key("router_logging").MustBool(false)
|
||||||
EnableGzip = server.Key("enable_gzip").MustBool(false)
|
EnableGzip = server.Key("enable_gzip").MustBool(false)
|
||||||
|
EnforceDomain = server.Key("enforce_domain").MustBool(false)
|
||||||
|
|
||||||
security := Cfg.Section("security")
|
security := Cfg.Section("security")
|
||||||
SecretKey = security.Key("secret_key").String()
|
SecretKey = security.Key("secret_key").String()
|
||||||
|
Reference in New Issue
Block a user