High severity7.8NVD Advisory· Published Apr 9, 2026· Updated Apr 17, 2026
CVE-2026-35205
CVE-2026-35205
Description
Helm is a package manager for Charts for Kubernetes. From 4.0.0 to 4.1.3, Helm will install plugins missing provenance (.prov file) when signature verification is required. This vulnerability is fixed in 4.1.4.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
helm.sh/helm/v4Go | >= 4.0.0, < 4.1.4 | 4.1.4 |
Affected products
1Patches
105fa37973dc9fix: Plugin missing provenance bypass
3 files changed · +55 −42
internal/plugin/installer/installer.go+16 −17 modified@@ -98,24 +98,23 @@ func InstallWithOptions(i Installer, opts Options) (*VerificationResult, error) // Check if provenance data exists if len(provData) == 0 { - // No .prov file found - emit warning but continue installation - fmt.Fprintf(os.Stderr, "WARNING: No provenance file found for plugin. Plugin is not signed and cannot be verified.\n") - } else { - // Provenance data exists - verify the plugin - verification, err := plugin.VerifyPlugin(archiveData, provData, filename, opts.Keyring) - if err != nil { - return nil, fmt.Errorf("plugin verification failed: %w", err) - } + return nil, fmt.Errorf("plugin verification failed: no provenance file (.prov) found") + } - // Collect verification info - result = &VerificationResult{ - SignedBy: make([]string, 0), - Fingerprint: fmt.Sprintf("%X", verification.SignedBy.PrimaryKey.Fingerprint), - FileHash: verification.FileHash, - } - for name := range verification.SignedBy.Identities { - result.SignedBy = append(result.SignedBy, name) - } + // Provenance data exists - verify the plugin + verification, err := plugin.VerifyPlugin(archiveData, provData, filename, opts.Keyring) + if err != nil { + return nil, fmt.Errorf("plugin verification failed: %w", err) + } + + // Collect verification info + result = &VerificationResult{ + SignedBy: make([]string, 0), + Fingerprint: fmt.Sprintf("%X", verification.SignedBy.PrimaryKey.Fingerprint), + FileHash: verification.FileHash, + } + for name := range verification.SignedBy.Identities { + result.SignedBy = append(result.SignedBy, name) } }
internal/plugin/installer/verification_test.go+36 −22 modified@@ -16,10 +16,8 @@ limitations under the License. package installer import ( - "bytes" "crypto/sha256" "fmt" - "io" "os" "path/filepath" "strings" @@ -44,33 +42,49 @@ func TestInstallWithOptions_VerifyMissingProvenance(t *testing.T) { } defer os.RemoveAll(installer.Path()) - // Capture stderr to check warning message - oldStderr := os.Stderr - r, w, _ := os.Pipe() - os.Stderr = w - - // Install with verification enabled (should warn but succeed) + // Install with verification enabled should fail when .prov is missing result, err := InstallWithOptions(installer, Options{Verify: true, Keyring: "dummy"}) - // Restore stderr and read captured output - w.Close() - os.Stderr = oldStderr - var buf bytes.Buffer - io.Copy(&buf, r) - output := buf.String() - - // Should succeed with nil result (no verification performed) - if err != nil { - t.Fatalf("Expected installation to succeed despite missing .prov file, got error: %v", err) + // Should fail with a missing provenance error + if err == nil { + t.Fatal("Expected installation to fail when .prov file is missing and verification is enabled") + } + if !strings.Contains(err.Error(), "no provenance file") { + t.Errorf("Expected 'no provenance file' in error message, got: %v", err) } if result != nil { t.Errorf("Expected nil verification result when .prov file is missing, got: %+v", result) } - // Should contain warning message - expectedWarning := "WARNING: No provenance file found for plugin" - if !strings.Contains(output, expectedWarning) { - t.Errorf("Expected warning message '%s' in output, got: %s", expectedWarning, output) + // Plugin should NOT be installed + if _, err := os.Stat(installer.Path()); !os.IsNotExist(err) { + t.Errorf("Plugin should not be installed when verification fails due to missing .prov") + } +} + +func TestInstallWithOptions_NoVerifyMissingProvenance(t *testing.T) { + ensure.HelmHome(t) + + // Create a temporary plugin tarball without .prov file + pluginDir := createTestPluginDir(t) + pluginTgz := createTarballFromPluginDir(t, pluginDir) + defer os.Remove(pluginTgz) + + // Create local installer + installer, err := NewLocalInstaller(pluginTgz) + if err != nil { + t.Fatalf("Failed to create installer: %v", err) + } + defer os.RemoveAll(installer.Path()) + + // Install with verification explicitly disabled should succeed without .prov + result, err := InstallWithOptions(installer, Options{Verify: false}) + + if err != nil { + t.Fatalf("Expected installation to succeed with --verify=false, got error: %v", err) + } + if result != nil { + t.Errorf("Expected nil verification result when verification is disabled, got: %+v", result) } // Plugin should be installed
pkg/cmd/plugin_install.go+3 −3 modified@@ -50,11 +50,11 @@ const pluginInstallDesc = ` This command allows you to install a plugin from a url to a VCS repo or a local path. By default, plugin signatures are verified before installation when installing from -tarballs (.tgz or .tar.gz). This requires a corresponding .prov file to be available -alongside the tarball. +tarballs (.tgz or .tar.gz). A corresponding .prov file must be available alongside +the tarball; installation will fail if it is missing or invalid. For local development, plugins installed from local directories are automatically treated as "local dev" and do not require signatures. -Use --verify=false to skip signature verification for remote plugins. +Use --verify=false to explicitly skip signature verification (NOT recommended). ` func newPluginInstallCmd(out io.Writer) *cobra.Command {
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
6- github.com/helm/helm/commit/05fa37973dc9e42b76e1d2883494c87174b6074fnvdPatchWEB
- github.com/advisories/GHSA-q5jf-9vfq-h4h7ghsaADVISORY
- github.com/helm/helm/security/advisories/GHSA-q5jf-9vfq-h4h7nvdVendor AdvisoryMitigationWEB
- nvd.nist.gov/vuln/detail/CVE-2026-35205ghsaADVISORY
- github.com/helm/helm/releases/tag/v4.1.4nvdProductRelease NotesWEB
- helm.sh/docs/topics/provenance/nvdProductWEB
News mentions
0No linked articles in our index yet.