server: ensure we reject access to the UI static files for users other than the UI user (#884)

This is for a scenario where a user provides valid username/password
but such that the username is not authorized to access the UI.

Previously we'd make it look like they got access (because they can
see the UI at leaast partially), but all API calls would fail.

With this change we're failing early with HTTP 403 and pointing the
users at a GH issue explaining what to do.

Fixes #580.
This commit is contained in:
Jarek Kowalski
2021-03-13 09:58:27 -08:00
committed by GitHub
parent 00807f9c49
commit 4efb06849e
2 changed files with 14 additions and 2 deletions

View File

@@ -87,10 +87,10 @@ func runServer(ctx context.Context, rep repo.Repository) error {
mux.Handle("/api/", srv.APIHandlers(*serverStartLegacyRepositoryAPI))
if *serverStartHTMLPath != "" {
fileServer := serveIndexFileForKnownUIRoutes(http.Dir(*serverStartHTMLPath))
fileServer := srv.RequireUIUserAuth(serveIndexFileForKnownUIRoutes(http.Dir(*serverStartHTMLPath)))
mux.Handle("/", fileServer)
} else if *serverStartUI {
mux.Handle("/", serveIndexFileForKnownUIRoutes(server.AssetFile()))
mux.Handle("/", srv.RequireUIUserAuth(serveIndexFileForKnownUIRoutes(server.AssetFile())))
}
httpServer := &http.Server{Addr: stripProtocol(*serverAddress)}

View File

@@ -238,6 +238,18 @@ func (s *Server) handleAPI(isAuthorized isAuthorizedFunc, f apiRequestFunc) http
})
}
// RequireUIUserAuth wraps the provided http.Handler to only allow UI user and return 403 otherwise.
func (s *Server) RequireUIUserAuth(hf http.Handler) http.Handler {
return s.requireAuth(func(rw http.ResponseWriter, r *http.Request) {
if !requireUIUser(s, r) {
http.Error(rw, `UI Access denied. See https://github.com/kopia/kopia/issues/880#issuecomment-798421751 for more information.`, http.StatusForbidden)
return
}
hf.ServeHTTP(rw, r)
})
}
func (s *Server) handleAPIPossiblyNotConnected(isAuthorized isAuthorizedFunc, f apiRequestFunc) http.HandlerFunc {
return s.requireAuth(func(w http.ResponseWriter, r *http.Request) {
// we must pre-read request body before acquiring the lock as it sometimes leads to deadlock