Skip to content

Commit

Permalink
fix(helm) tighten up helm requests [EE-6722] (#11233)
Browse files Browse the repository at this point in the history
  • Loading branch information
hookenz committed Feb 21, 2024
1 parent 1cdd3fd commit 8f9b265
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
15 changes: 9 additions & 6 deletions api/http/handler/helm/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,20 @@ func NewHandler(bouncer security.BouncerService, dataStore dataservices.DataStor
kubeClusterAccessService: kubeClusterAccessService,
}

h.Use(middlewares.WithEndpoint(dataStore.Endpoint(), "id"))
h.Use(middlewares.WithEndpoint(dataStore.Endpoint(), "id"),
bouncer.AuthenticatedAccess)

// `helm list -o json`
h.Handle("/{id}/kubernetes/helm",
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.helmList))).Methods(http.MethodGet)
httperror.LoggerHandler(h.helmList)).Methods(http.MethodGet)

// `helm delete RELEASE_NAME`
h.Handle("/{id}/kubernetes/helm/{release}",
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.helmDelete))).Methods(http.MethodDelete)
httperror.LoggerHandler(h.helmDelete)).Methods(http.MethodDelete)

// `helm install [NAME] [CHART] flags`
h.Handle("/{id}/kubernetes/helm",
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.helmInstall))).Methods(http.MethodPost)
httperror.LoggerHandler(h.helmInstall)).Methods(http.MethodPost)

// Deprecated
h.Handle("/{id}/kubernetes/helm/repositories",
Expand All @@ -69,12 +70,14 @@ func NewTemplateHandler(bouncer security.BouncerService, helmPackageManager libh
requestBouncer: bouncer,
}

h.Use(bouncer.AuthenticatedAccess)

h.Handle("/templates/helm",
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.helmRepoSearch))).Methods(http.MethodGet)
httperror.LoggerHandler(h.helmRepoSearch)).Methods(http.MethodGet)

// helm show [COMMAND] [CHART] [REPO] flags
h.Handle("/templates/helm/{command:chart|values|readme}",
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.helmShow))).Methods(http.MethodGet)
httperror.LoggerHandler(h.helmShow)).Methods(http.MethodGet)

return h
}
Expand Down
34 changes: 31 additions & 3 deletions pkg/libhelm/binary/search_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
)

var errRequiredSearchOptions = errors.New("repo is required")
var errInvalidRepoURL = errors.New("the request failed since either the Helm repository was not found or the index.yaml is not valid")

type File struct {
APIVersion string `yaml:"apiVersion" json:"apiVersion"`
Expand Down Expand Up @@ -64,6 +65,11 @@ func (hbpm *helmBinaryPackageManager) SearchRepo(searchRepoOpts options.SearchRe
}
}

// Allow redirect behavior to be overriden if specified.
if client.CheckRedirect == nil {
client.CheckRedirect = defaultCheckRedirect
}

url, err := url.ParseRequestURI(searchRepoOpts.Repo)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("invalid helm chart URL: %s", searchRepoOpts.Repo))
Expand All @@ -72,20 +78,42 @@ func (hbpm *helmBinaryPackageManager) SearchRepo(searchRepoOpts options.SearchRe
url.Path = path.Join(url.Path, "index.yaml")
resp, err := client.Get(url.String())
if err != nil {
return nil, errors.Wrap(err, "failed to get index file")
return nil, errInvalidRepoURL
}
defer resp.Body.Close()

var file File
err = yaml.NewDecoder(resp.Body).Decode(&file)
if err != nil {
return nil, errors.Wrap(err, "failed to decode index file")
return nil, errInvalidRepoURL
}

// Validate index.yaml
if file.APIVersion == "" || file.Entries == nil {
return nil, errInvalidRepoURL
}

result, err := json.Marshal(file)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal index file")
return nil, errInvalidRepoURL
}

return result, nil
}

// defaultCheckRedirect is a default CheckRedirect for helm
// We don't allow redirects to URLs not ending in index.yaml
// After that we follow the go http client behavior which is to stop
// after a maximum of 10 redirects
func defaultCheckRedirect(req *http.Request, via []*http.Request) error {
// The request url must end in index.yaml
if path.Base(req.URL.Path) != "index.yaml" {
return errors.New("the request URL must end in index.yaml")
}

// default behavior below
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
return nil
}
2 changes: 1 addition & 1 deletion pkg/libhelm/binary/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (hbpm *helmBinaryPackageManager) Show(showOpts options.ShowOptions) ([]byte

result, err := hbpm.run("show", args, showOpts.Env)
if err != nil {
return nil, errors.Wrap(err, "failed to run helm show on specified args")
return nil, errors.New("the request failed since either the Helm repository was not found or the chart does not exist")
}

return result, nil
Expand Down

0 comments on commit 8f9b265

Please sign in to comment.