VYPR
Moderate severityNVD Advisory· Published Apr 9, 2025· Updated Apr 10, 2025

Helm Allows A Specially Crafted JSON Schema To Cause A Stack Overflow

CVE-2025-32387

Description

Helm is a package manager for Charts for Kubernetes. A JSON Schema file within a chart can be crafted with a deeply nested chain of references, leading to parser recursion that can exceed the stack size limit and trigger a stack overflow. This issue has been resolved in Helm v3.17.3.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
helm.sh/helm/v3Go
< 3.17.33.17.3

Affected products

1

Patches

1
d8ca55fc6696

Merge commit from fork

https://github.com/helm/helmMatt FarinaApr 9, 2025via ghsa
2 files changed · +35 1
  • pkg/chart/v2/loader/archive.go+31 1 modified
    @@ -33,6 +33,15 @@ import (
     	chart "helm.sh/helm/v4/pkg/chart/v2"
     )
     
    +// MaxDecompressedChartSize is the maximum size of a chart archive that will be
    +// decompressed. This is the decompressed size of all the files.
    +// The default value is 100 MiB.
    +var MaxDecompressedChartSize int64 = 100 * 1024 * 1024 // Default 100 MiB
    +
    +// MaxDecompressedFileSize is the size of the largest file that Helm will attempt to load.
    +// The size of the file is the decompressed version of it when it is stored in an archive.
    +var MaxDecompressedFileSize int64 = 5 * 1024 * 1024 // Default 5 MiB
    +
     var drivePathPattern = regexp.MustCompile(`^[a-zA-Z]:/`)
     
     // FileLoader loads a chart from a file
    @@ -119,6 +128,7 @@ func LoadArchiveFiles(in io.Reader) ([]*BufferedFile, error) {
     
     	files := []*BufferedFile{}
     	tr := tar.NewReader(unzipped)
    +	remainingSize := MaxDecompressedChartSize
     	for {
     		b := bytes.NewBuffer(nil)
     		hd, err := tr.Next()
    @@ -178,10 +188,30 @@ func LoadArchiveFiles(in io.Reader) ([]*BufferedFile, error) {
     			return nil, errors.New("chart yaml not in base directory")
     		}
     
    -		if _, err := io.Copy(b, tr); err != nil {
    +		if hd.Size > remainingSize {
    +			return nil, fmt.Errorf("decompressed chart is larger than the maximum size %d", MaxDecompressedChartSize)
    +		}
    +
    +		if hd.Size > MaxDecompressedFileSize {
    +			return nil, fmt.Errorf("decompressed chart file %q is larger than the maximum file size %d", hd.Name, MaxDecompressedFileSize)
    +		}
    +
    +		limitedReader := io.LimitReader(tr, remainingSize)
    +
    +		bytesWritten, err := io.Copy(b, limitedReader)
    +		if err != nil {
     			return nil, err
     		}
     
    +		remainingSize -= bytesWritten
    +		// When the bytesWritten are less than the file size it means the limit reader ended
    +		// copying early. Here we report that error. This is important if the last file extracted
    +		// is the one that goes over the limit. It assumes the Size stored in the tar header
    +		// is correct, something many applications do.
    +		if bytesWritten < hd.Size || remainingSize <= 0 {
    +			return nil, fmt.Errorf("decompressed chart is larger than the maximum size %d", MaxDecompressedChartSize)
    +		}
    +
     		data := bytes.TrimPrefix(b.Bytes(), utf8bom)
     
     		files = append(files, &BufferedFile{Name: n, Data: data})
    
  • pkg/chart/v2/loader/directory.go+4 0 modified
    @@ -101,6 +101,10 @@ func LoadDir(dir string) (*chart.Chart, error) {
     			return fmt.Errorf("cannot load irregular file %s as it has file mode type bits set", name)
     		}
     
    +		if fi.Size() > MaxDecompressedFileSize {
    +			return fmt.Errorf("chart file %q is larger than the maximum file size %d", fi.Name(), MaxDecompressedFileSize)
    +		}
    +
     		data, err := os.ReadFile(name)
     		if err != nil {
     			return errors.Wrapf(err, "error reading %s", n)
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.