Skip to content

Commit

Permalink
Merge pull request from GHSA-g687-f2gx-6wm8
Browse files Browse the repository at this point in the history
* feat: use untar with limiter

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: use untar with limiter

Signed-off-by: pashakostohrys <pavel@codefresh.io>

---------

Signed-off-by: pashakostohrys <pavel@codefresh.io>
  • Loading branch information
pasha-codefresh committed Sep 7, 2023
1 parent 4b55084 commit 44e52c4
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 11 deletions.
8 changes: 8 additions & 0 deletions cmd/argocd-repo-server/commands/argocd_repo_server.go
Expand Up @@ -82,6 +82,8 @@ func NewCommand() *cobra.Command {
allowOutOfBoundsSymlinks bool
streamedManifestMaxTarSize string
streamedManifestMaxExtractedSize string
helmManifestMaxExtractedSize string
disableManifestMaxExtractedSize bool
)
var command = cobra.Command{
Use: cliName,
Expand Down Expand Up @@ -120,6 +122,9 @@ func NewCommand() *cobra.Command {
streamedManifestMaxExtractedSizeQuantity, err := resource.ParseQuantity(streamedManifestMaxExtractedSize)
errors.CheckError(err)

helmManifestMaxExtractedSizeQuantity, err := resource.ParseQuantity(helmManifestMaxExtractedSize)
errors.CheckError(err)

askPassServer := askpass.NewServer()
metricsServer := metrics.NewMetricsServer()
cacheutil.CollectMetrics(redisClient, metricsServer)
Expand All @@ -134,6 +139,7 @@ func NewCommand() *cobra.Command {
AllowOutOfBoundsSymlinks: allowOutOfBoundsSymlinks,
StreamedManifestMaxExtractedSize: streamedManifestMaxExtractedSizeQuantity.ToDec().Value(),
StreamedManifestMaxTarSize: streamedManifestMaxTarSizeQuantity.ToDec().Value(),
HelmManifestMaxExtractedSize: helmManifestMaxExtractedSizeQuantity.ToDec().Value(),
}, askPassServer)
errors.CheckError(err)

Expand Down Expand Up @@ -216,6 +222,8 @@ func NewCommand() *cobra.Command {
command.Flags().BoolVar(&allowOutOfBoundsSymlinks, "allow-oob-symlinks", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS", false), "Allow out-of-bounds symlinks in repositories (not recommended)")
command.Flags().StringVar(&streamedManifestMaxTarSize, "streamed-manifest-max-tar-size", env.StringFromEnv("ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE", "100M"), "Maximum size of streamed manifest archives")
command.Flags().StringVar(&streamedManifestMaxExtractedSize, "streamed-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of streamed manifest archives when extracted")
command.Flags().StringVar(&helmManifestMaxExtractedSize, "helm-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of helm manifest archives when extracted")
command.Flags().BoolVar(&disableManifestMaxExtractedSize, "disable-helm-manifest-max-extracted-size", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE", false), "Disable maximum size of helm manifest archives when extracted")
tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command)
cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) {
redisClient = client
Expand Down
2 changes: 2 additions & 0 deletions docs/operator-manual/server-commands/argocd-repo-server.md
Expand Up @@ -16,7 +16,9 @@ argocd-repo-server [flags]
--address string Listen on given address for incoming connections (default "0.0.0.0")
--allow-oob-symlinks Allow out-of-bounds symlinks in repositories (not recommended)
--default-cache-expiration duration Cache expiration default (default 24h0m0s)
--disable-helm-manifest-max-extracted-size Disable maximum size of helm manifest archives when extracted
--disable-tls Disable TLS on the gRPC endpoint
--helm-manifest-max-extracted-size string Maximum size of helm manifest archives when extracted (default "1G")
-h, --help help for argocd-repo-server
--logformat string Set the logging format. One of: text|json (default "text")
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
Expand Down
12 changes: 12 additions & 0 deletions manifests/base/repo-server/argocd-repo-server-deployment.yaml
Expand Up @@ -150,6 +150,18 @@ spec:
key: reposerver.streamed.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
name: argocd-cmd-params-cm
key: reposerver.disable.helm.manifest.max.extracted.size
optional: true
- name: ARGOCD_GIT_MODULES_ENABLED
valueFrom:
configMapKeyRef:
Expand Down
12 changes: 12 additions & 0 deletions manifests/core-install.yaml
Expand Up @@ -19156,6 +19156,18 @@ spec:
key: reposerver.streamed.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.disable.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_GIT_MODULES_ENABLED
valueFrom:
configMapKeyRef:
Expand Down
12 changes: 12 additions & 0 deletions manifests/ha/install.yaml
Expand Up @@ -20612,6 +20612,18 @@ spec:
key: reposerver.streamed.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.disable.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_GIT_MODULES_ENABLED
valueFrom:
configMapKeyRef:
Expand Down
12 changes: 12 additions & 0 deletions manifests/ha/namespace-install.yaml
Expand Up @@ -2130,6 +2130,18 @@ spec:
key: reposerver.streamed.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.disable.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_GIT_MODULES_ENABLED
valueFrom:
configMapKeyRef:
Expand Down
12 changes: 12 additions & 0 deletions manifests/install.yaml
Expand Up @@ -19669,6 +19669,18 @@ spec:
key: reposerver.streamed.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.disable.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_GIT_MODULES_ENABLED
valueFrom:
configMapKeyRef:
Expand Down
12 changes: 12 additions & 0 deletions manifests/namespace-install.yaml
Expand Up @@ -1187,6 +1187,18 @@ spec:
key: reposerver.streamed.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE
valueFrom:
configMapKeyRef:
key: reposerver.disable.helm.manifest.max.extracted.size
name: argocd-cmd-params-cm
optional: true
- name: ARGOCD_GIT_MODULES_ENABLED
valueFrom:
configMapKeyRef:
Expand Down
6 changes: 4 additions & 2 deletions reposerver/repository/repository.go
Expand Up @@ -107,6 +107,8 @@ type RepoServerInitConstants struct {
AllowOutOfBoundsSymlinks bool
StreamedManifestMaxExtractedSize int64
StreamedManifestMaxTarSize int64
HelmManifestMaxExtractedSize int64
DisableHelmManifestMaxExtractedSize bool
}

// NewService returns a new instance of the Manifest service
Expand Down Expand Up @@ -346,7 +348,7 @@ func (s *Service) runRepoOperation(
if source.Helm != nil {
helmPassCredentials = source.Helm.PassCredentials
}
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, helmPassCredentials)
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, helmPassCredentials, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
if err != nil {
return err
}
Expand Down Expand Up @@ -2233,7 +2235,7 @@ func (s *Service) GetRevisionChartDetails(ctx context.Context, q *apiclient.Repo
if err != nil {
return nil, fmt.Errorf("helm client error: %v", err)
}
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, false)
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, false, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
if err != nil {
return nil, fmt.Errorf("error extracting chart: %v", err)
}
Expand Down
25 changes: 19 additions & 6 deletions util/helm/client.go
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"fmt"
executil "github.com/argoproj/argo-cd/v2/util/exec"
"io"
"net/http"
"net/url"
Expand All @@ -25,7 +26,6 @@ import (
"oras.land/oras-go/v2/registry/remote/auth"

"github.com/argoproj/argo-cd/v2/util/cache"
executil "github.com/argoproj/argo-cd/v2/util/exec"
argoio "github.com/argoproj/argo-cd/v2/util/io"
"github.com/argoproj/argo-cd/v2/util/io/files"
"github.com/argoproj/argo-cd/v2/util/proxy"
Expand All @@ -52,7 +52,7 @@ type indexCache interface {

type Client interface {
CleanChartCache(chart string, version string) error
ExtractChart(chart string, version string, passCredentials bool) (string, argoio.Closer, error)
ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error)
GetIndex(noCache bool) (*Index, error)
GetTags(chart string, noCache bool) (*TagsList, error)
TestHelmOCI() (bool, error)
Expand Down Expand Up @@ -122,7 +122,21 @@ func (c *nativeHelmChart) CleanChartCache(chart string, version string) error {
return os.RemoveAll(cachePath)
}

func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredentials bool) (string, argoio.Closer, error) {
func untarChart(tempDir string, cachedChartPath string, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) error {
if disableManifestMaxExtractedSize {
cmd := exec.Command("tar", "-zxvf", cachedChartPath)
cmd.Dir = tempDir
_, err := executil.Run(cmd)
return err
}
reader, err := os.Open(cachedChartPath)
if err != nil {
return err
}
return files.Untgz(tempDir, reader, manifestMaxExtractedSize, false)
}

func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error) {
// always use Helm V3 since we don't have chart content to determine correct Helm version
helmCmd, err := NewCmdWithVersion("", HelmV3, c.enableOci, c.proxy)

Expand Down Expand Up @@ -196,15 +210,14 @@ func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredent
if len(infos) != 1 {
return "", nil, fmt.Errorf("expected 1 file, found %v", len(infos))
}

err = os.Rename(filepath.Join(tempDest, infos[0].Name()), cachedChartPath)
if err != nil {
return "", nil, err
}
}

cmd := exec.Command("tar", "-zxvf", cachedChartPath)
cmd.Dir = tempDir
_, err = executil.Run(cmd)
err = untarChart(tempDir, cachedChartPath, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
if err != nil {
_ = os.RemoveAll(tempDir)
return "", nil, err
Expand Down
11 changes: 9 additions & 2 deletions util/helm/client_test.go
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"math"
"os"
"strings"
"testing"
Expand Down Expand Up @@ -71,17 +72,23 @@ func TestIndex(t *testing.T) {

func Test_nativeHelmChart_ExtractChart(t *testing.T) {
client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "")
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false)
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true)
assert.NoError(t, err)
defer io.Close(closer)
info, err := os.Stat(path)
assert.NoError(t, err)
assert.True(t, info.IsDir())
}

func Test_nativeHelmChart_ExtractChartWithLimiter(t *testing.T) {
client := NewClient("https://argoproj.github.io/argo-helm", Creds{}, false, "")
_, _, err := client.ExtractChart("argo-cd", "0.7.1", false, 100, false)
assert.Error(t, err, "error while iterating on tar reader: unexpected EOF")
}

func Test_nativeHelmChart_ExtractChart_insecure(t *testing.T) {
client := NewClient("https://argoproj.github.io/argo-helm", Creds{InsecureSkipVerify: true}, false, "")
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false)
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true)
assert.NoError(t, err)
defer io.Close(closer)
info, err := os.Stat(path)
Expand Down
2 changes: 1 addition & 1 deletion util/helm/mocks/Client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 44e52c4

Please sign in to comment.