lib/config, cmd/syncthing: Enforce localhost only connections

When the GUI/API is bound to localhost, we enforce that the Host header
looks like localhost. This can be disabled by setting
insecureSkipHostCheck in the GUI config.

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3558
This commit is contained in:
Jakob Borg
2016-09-03 08:33:34 +00:00
committed by Audrius Butkevicius
parent 46a143e80e
commit 49910a1d85
3 changed files with 233 additions and 12 deletions

View File

@@ -313,6 +313,11 @@ func (s *apiService) Serve() {
// Add the CORS handling
handler = corsMiddleware(handler)
if addressIsLocalhost(guiCfg.Address()) && !guiCfg.InsecureSkipHostCheck {
// Verify source host
handler = localhostMiddleware(handler)
}
handler = debugMiddleware(handler)
srv := http.Server{
@@ -495,6 +500,17 @@ func withDetailsMiddleware(id protocol.DeviceID, h http.Handler) http.Handler {
})
}
func localhostMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if addressIsLocalhost(r.Host) {
h.ServeHTTP(w, r)
return
}
http.Error(w, "Host check error", http.StatusForbidden)
})
}
func (s *apiService) whenDebugging(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if s.cfg.GUI().Debugging {
@@ -503,7 +519,6 @@ func (s *apiService) whenDebugging(h http.Handler) http.Handler {
}
http.Error(w, "Debugging disabled", http.StatusBadRequest)
return
})
}
@@ -1292,3 +1307,17 @@ func dirNames(dir string) []string {
sort.Strings(dirs)
return dirs
}
func addressIsLocalhost(addr string) bool {
host, _, err := net.SplitHostPort(addr)
if err != nil {
// There was no port, so we assume the address was just a hostname
host = addr
}
switch host {
case "127.0.0.1", "::1", "localhost":
return true
default:
return false
}
}