From 91e550b7154e85cd6dde6c7008e8c3bf69e2b733 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 24 Feb 2022 00:05:42 -0800 Subject: [PATCH] bake: add path validation for remote bake invocations This is a stopgap before proper entitlements support is implemented. Signed-off-by: Tonis Tiigi --- bake/bake.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/bake/bake.go b/bake/bake.go index e703860e..82d7d921 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "path" + "path/filepath" "regexp" "sort" "strconv" @@ -744,6 +745,59 @@ func updateContext(t *build.Inputs, inp *Input) { t.ContextState = &st } +// validateContextsEntitlements is a basic check to ensure contexts do not +// escape local directories when loaded from remote sources. This is to be +// replaced with proper entitlements support in the future. +func validateContextsEntitlements(t build.Inputs, inp *Input) error { + if inp == nil || inp.State == nil { + return nil + } + if v, ok := os.LookupEnv("BAKE_ALLOW_REMOTE_FS_ACCESS"); ok { + if vv, _ := strconv.ParseBool(v); vv { + return nil + } + } + if t.ContextState == nil { + if err := checkPath(t.ContextPath); err != nil { + return err + } + } + for _, v := range t.NamedContexts { + if v.State != nil { + continue + } + if err := checkPath(v.Path); err != nil { + return err + } + } + return nil +} + +func checkPath(p string) error { + if IsRemoteURL(p) || strings.HasPrefix(p, "target:") || strings.HasPrefix(p, "docker-image:") { + return nil + } + p, err := filepath.EvalSymlinks(p) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + wd, err := os.Getwd() + if err != nil { + return err + } + rel, err := filepath.Rel(wd, p) + if err != nil { + return err + } + if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) { + return errors.Errorf("path %s is outside of the working directory, please set BAKE_ALLOW_REMOTE_FS_ACCESS=1", p) + } + return nil +} + func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { if v := t.Context; v != nil && *v == "-" { return nil, errors.Errorf("context from stdin not allowed in bake") @@ -799,6 +853,10 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { } } + if err := validateContextsEntitlements(bi, inp); err != nil { + return nil, err + } + t.Context = &bi.ContextPath bo := &build.Options{