From 3f6fed5df2e9ecaf32c134d7015de72dda2a4bc6 Mon Sep 17 00:00:00 2001 From: Max Asnaashari Date: Wed, 4 Sep 2024 18:58:43 +0000 Subject: [PATCH] api: Add validator Signed-off-by: Max Asnaashari --- api/services_tokens.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/api/services_tokens.go b/api/services_tokens.go index 43023d4c2..0cbe619ad 100644 --- a/api/services_tokens.go +++ b/api/services_tokens.go @@ -2,10 +2,13 @@ package api import ( "encoding/json" + "errors" "fmt" "net/http" "net/url" "os" + "path/filepath" + "strings" "github.com/canonical/lxd/lxd/response" "github.com/canonical/microcluster/rest" @@ -27,6 +30,24 @@ var ServiceTokensCmd = func(sh *service.Handler) rest.Endpoint { } } +func IsSafeVarPath(path string) error { + absPath, err := filepath.Abs(path) + if err != nil { + return err + } + + varDir := os.Getenv("LXD_DIR") + if varDir == "" { + varDir = "/var/lib/lxd" + } + + if !strings.HasPrefix(absPath, varDir) { + return errors.New("Absolute path is outside the default LXD path") + } + + return nil +} + // serviceTokensPost issues a token for service using the MicroCloud proxy. // Normally a token request to a service would be restricted to trusted systems, // so this endpoint validates the mDNS auth token and then proxies the request to the local unix socket of the remote system. @@ -44,6 +65,11 @@ func serviceTokensPost(s *state.State, r *http.Request) response.Response { return response.BadRequest(err) } + err = IsSafeVarPath(req.JoinerName) + if err != nil { + return response.SmartError(err) + } + _ = os.MkdirAll(req.JoinerName, 0700) sh, err := service.NewHandler(s.Name(), req.ClusterAddress, s.OS.StateDir, false, false, types.ServiceType(serviceType))