Skip to content

Commit

Permalink
Update Helm to v3.6.1
Browse files Browse the repository at this point in the history
v3.6.1 is a a security update from Helm, ensuring that credentials are
always only passed to the defined repository host.

Based on Helm user reports, disabling this behavior may be required for
some Helm repository solutions like Artifactory, and may be done by
setting `PassCredentials` in the `HelmRepositorySpec`.

For more information, see:
GHSA-56hp-xqp3-w2jf

Signed-off-by: Hidde Beydals <hello@hidde.co>
  • Loading branch information
hiddeco committed Jun 18, 2021
1 parent 1a75415 commit 1f27410
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 17 deletions.
9 changes: 9 additions & 0 deletions api/v1beta1/helmrepository_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ type HelmRepositorySpec struct {
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`

// PassCredentials allows the credentials from the SecretRef to be passed on to
// a host that does not match the host as defined in URL.
// This may be required if the host of the advertised chart URLs in the index
// differ from the defined URL.
// Enabling this should be done with caution, as it can potentially result in
// credentials getting stolen in a MITM-attack.
// +optional
PassCredentials bool `json:"passCredentials,omitempty"`

// The interval at which to check the upstream for updates.
// +required
Interval metav1.Duration `json:"interval"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ spec:
interval:
description: The interval at which to check the upstream for updates.
type: string
passCredentials:
description: PassCredentials allows the credentials from the SecretRef to be passed on to a host that does not match the host as defined in URL. This may be required if the host of the advertised chart URLs in the index differ from the defined URL. Enabling this should be done with caution, as it can potentially result in credentials getting stolen in a MITM-attack.
type: boolean
secretRef:
description: The name of the secret containing authentication credentials for the Helm repository. For HTTP/S basic auth the secret must contain username and password fields. For TLS the secret must contain a certFile and keyFile, and/or caCert fields.
properties:
Expand Down
22 changes: 14 additions & 8 deletions controllers/helmchart_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,11 @@ func (r *HelmChartReconciler) getSource(ctx context.Context, chart sourcev1.Helm
func (r *HelmChartReconciler) reconcileFromHelmRepository(ctx context.Context,
repository sourcev1.HelmRepository, chart sourcev1.HelmChart, force bool) (sourcev1.HelmChart, error) {
// Configure ChartRepository getter options
var clientOpts []getter.Option
clientOpts := []getter.Option{
getter.WithURL(repository.Spec.URL),
getter.WithTimeout(repository.Spec.Timeout.Duration),
getter.WithPassCredentialsAll(repository.Spec.PassCredentials),
}
if secret, err := r.getHelmRepositorySecret(ctx, &repository); err != nil {
return sourcev1.HelmChartNotReady(chart, sourcev1.AuthenticationFailedReason, err.Error()), err
} else if secret != nil {
Expand All @@ -311,10 +315,8 @@ func (r *HelmChartReconciler) reconcileFromHelmRepository(ctx context.Context,
return sourcev1.HelmChartNotReady(chart, sourcev1.AuthenticationFailedReason, err.Error()), err
}
defer cleanup()

clientOpts = opts
clientOpts = append(clientOpts, opts...)
}
clientOpts = append(clientOpts, getter.WithTimeout(repository.Spec.Timeout.Duration))

// Initialize the chart repository and load the index file
chartRepo, err := helm.NewChartRepository(repository.Spec.URL, r.Getters, clientOpts)
Expand Down Expand Up @@ -619,13 +621,18 @@ func (r *HelmChartReconciler) reconcileFromTarballArtifact(ctx context.Context,
if err != nil {
repository = &sourcev1.HelmRepository{
Spec: sourcev1.HelmRepositorySpec{
URL: dep.Repository,
URL: dep.Repository,
Timeout: &metav1.Duration{Duration: 60 * time.Second},
},
}
}

// Configure ChartRepository getter options
var clientOpts []getter.Option
clientOpts := []getter.Option{
getter.WithURL(repository.Spec.URL),
getter.WithTimeout(repository.Spec.Timeout.Duration),
getter.WithPassCredentialsAll(repository.Spec.PassCredentials),
}
if secret, err := r.getHelmRepositorySecret(ctx, repository); err != nil {
return sourcev1.HelmChartNotReady(chart, sourcev1.AuthenticationFailedReason, err.Error()), err
} else if secret != nil {
Expand All @@ -635,8 +642,7 @@ func (r *HelmChartReconciler) reconcileFromTarballArtifact(ctx context.Context,
return sourcev1.HelmChartNotReady(chart, sourcev1.AuthenticationFailedReason, err.Error()), err
}
defer cleanup()

clientOpts = opts
clientOpts = append(clientOpts, opts...)
}

// Initialize the chart repository and load the index file
Expand Down
6 changes: 3 additions & 3 deletions controllers/helmchart_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1015,9 +1015,9 @@ var _ = Describe("HelmChartReconciler", func() {
Name: secretKey.Name,
Namespace: secretKey.Namespace,
},
Data: map[string][]byte{
"username": []byte(username),
"password": []byte(password),
StringData: map[string]string{
"username": username,
"password": password,
},
}
Expect(k8sClient.Create(context.Background(), secret)).Should(Succeed())
Expand Down
9 changes: 6 additions & 3 deletions controllers/helmrepository_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,11 @@ func (r *HelmRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reque
}

func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, repository sourcev1.HelmRepository) (sourcev1.HelmRepository, error) {
var clientOpts []getter.Option
clientOpts := []getter.Option{
getter.WithURL(repository.Spec.URL),
getter.WithTimeout(repository.Spec.Timeout.Duration),
getter.WithPassCredentialsAll(repository.Spec.PassCredentials),
}
if repository.Spec.SecretRef != nil {
name := types.NamespacedName{
Namespace: repository.GetNamespace(),
Expand All @@ -191,9 +195,8 @@ func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, repository sou
return sourcev1.HelmRepositoryNotReady(repository, sourcev1.AuthenticationFailedReason, err.Error()), err
}
defer cleanup()
clientOpts = opts
clientOpts = append(clientOpts, opts...)
}
clientOpts = append(clientOpts, getter.WithTimeout(repository.Spec.Timeout.Duration))

chartRepo, err := helm.NewChartRepository(repository.Spec.URL, r.Getters, clientOpts)
if err != nil {
Expand Down
34 changes: 34 additions & 0 deletions docs/api/source.md
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,23 @@ caCert fields.</p>
</tr>
<tr>
<td>
<code>passCredentials</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>PassCredentials allows the credentials from the SecretRef to be passed on to
a host that does not match the host as defined in URL.
This may be required if the host of the advertised chart URLs in the index
differ from the defined URL.
Enabling this should be done with caution, as it can potentially result in
credentials getting stolen in a MITM-attack.</p>
</td>
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
Expand Down Expand Up @@ -1777,6 +1794,23 @@ caCert fields.</p>
</tr>
<tr>
<td>
<code>passCredentials</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>PassCredentials allows the credentials from the SecretRef to be passed on to
a host that does not match the host as defined in URL.
This may be required if the host of the advertised chart URLs in the index
differ from the defined URL.
Enabling this should be done with caution, as it can potentially result in
credentials getting stolen in a MITM-attack.</p>
</td>
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
Expand Down
11 changes: 10 additions & 1 deletion docs/spec/v1beta1/helmrepositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@ type HelmRepositorySpec struct {
// password fields.
// For TLS the secret must contain a certFile and keyFile, and/or
// caCert fields.
// +optional
// +optional
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`

// PassCredentials allows the credentials from the SecretRef to be passed on to
// a host that does not match the host as defined in URL.
// This may be required if the host of the advertised chart URLs in the index
// differ from the defined URL.
// Enabling this should be done with caution, as it can potentially result in
// credentials getting stolen in a MITM-attack.
// +optional
PassCredentials bool `json:"passCredentials,omitempty"`

// The interval at which to check the upstream for updates.
// +required
Interval metav1.Duration `json:"interval"`
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ require (
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
gotest.tools v2.2.0+incompatible
helm.sh/helm/v3 v3.6.0
helm.sh/helm/v3 v3.6.1
k8s.io/api v0.21.1
k8s.io/apimachinery v0.21.1
k8s.io/client-go v0.21.1
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1247,8 +1247,9 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
helm.sh/helm/v3 v3.6.0 h1:/9IMxJ2lXJHbvTMHcW1AO71lXQHqDC+3bcpGp7yCsb8=
helm.sh/helm/v3 v3.6.0/go.mod h1:mIIus8EOqj+obtycw3sidsR4ORr2aFDmXMSI3k+oeVY=
helm.sh/helm/v3 v3.6.1 h1:TQ6q4pAatXr7qh2fbLcb0oNd0I3J7kv26oo5cExKTtc=
helm.sh/helm/v3 v3.6.1/go.mod h1:mIIus8EOqj+obtycw3sidsR4ORr2aFDmXMSI3k+oeVY=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down

0 comments on commit 1f27410

Please sign in to comment.