VYPR
Medium severity6.5GHSA Advisory· Published May 9, 2026· Updated May 14, 2026

CVE-2026-42183

CVE-2026-42183

Description

Argo Workflows is an open source container-native workflow engine for orchestrating parallel jobs on Kubernetes. From version 4.0.0 to before version 4.0.5, a nil pointer dereference in server/auth/gatekeeper.go rbacAuthorization() causes a panic (denial of service) for SSO users whose claims match a namespace-level RBAC rule but not an SSO-namespace rule, when SSO_DELEGATE_RBAC_TO_NAMESPACE=true. This issue has been patched in version 4.0.5.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/argoproj/argo-workflows/v4Go
>= 4.0.0, < 4.0.54.0.5

Affected products

2
  • Argoproj/Argo WorkflowsGHSA2 versions
    >= 4.0.0, <= 4.0.4+ 1 more
    • (no CPE)range: >= 4.0.0, <= 4.0.4
    • cpe:2.3:a:argoproj:argo_workflows:*:*:*:*:*:go:*:*range: >=4.0.0,<4.0.5

Patches

1
c4cc17d0c034

Merge commit from fork

https://github.com/argoproj/argo-workflowsAlan ClucasApr 23, 2026via ghsa
2 files changed · +34 4
  • server/auth/gatekeeper.go+7 4 modified
    @@ -301,7 +301,7 @@ func (s *gatekeeper) rbacAuthorization(ctx context.Context, claims *authTypes.Cl
     		namespaceAccount, err := s.getServiceAccount(claims, getNamespace(req))
     		if err != nil {
     			logger.WithError(err).Info(ctx, "Error while SSO Delegation")
    -		} else if precedence(namespaceAccount) > precedence(loginAccount) {
    +		} else if loginAccount == nil || precedence(namespaceAccount) > precedence(loginAccount) {
     			delegatedAccount = namespaceAccount
     			ssoDelegated = true
     		}
    @@ -310,14 +310,17 @@ func (s *gatekeeper) rbacAuthorization(ctx context.Context, claims *authTypes.Cl
     		return nil, fmt.Errorf("no service account rule matches")
     	}
     	// important! write an audit entry (i.e. log entry) so we know which user performed an operation
    -	logger.WithFields(logging.Fields{
    +	fields := logging.Fields{
     		"serviceAccount":       delegatedAccount.Name,
    -		"loginServiceAccount":  loginAccount.Name,
     		"subject":              claims.Subject,
     		"email":                claims.Email,
     		"ssoDelegationAllowed": ssoDelegationAllowed,
     		"ssoDelegated":         ssoDelegated,
    -	}).Info(ctx, "selected SSO RBAC service account for user")
    +	}
    +	if loginAccount != nil {
    +		fields["loginServiceAccount"] = loginAccount.Name
    +	}
    +	logger.WithFields(fields).Info(ctx, "selected SSO RBAC service account for user")
     	return s.getClientsForServiceAccount(ctx, claims, delegatedAccount)
     }
     
    
  • server/auth/gatekeeper_test.go+27 0 modified
    @@ -58,6 +58,16 @@ func TestServer_GetWFClient(t *testing.T) {
     			},
     			Secrets: []corev1.ObjectReference{{Name: "user-secret"}},
     		},
    +		&corev1.ServiceAccount{
    +			ObjectMeta: metav1.ObjectMeta{
    +				Name: "user1-only-sa", Namespace: "user1-ns",
    +				Annotations: map[string]string{
    +					common.AnnotationKeyRBACRule:           "'user1-only-group' in groups",
    +					common.AnnotationKeyRBACRulePrecedence: "0",
    +				},
    +			},
    +			Secrets: []corev1.ObjectReference{{Name: "user-secret"}},
    +		},
     		&corev1.ServiceAccount{
     			ObjectMeta: metav1.ObjectMeta{
     				Name: "user2-sa", Namespace: "user2-ns",
    @@ -240,6 +250,23 @@ func TestServer_GetWFClient(t *testing.T) {
     		assert.Equal(t, "my-sa", claims.ServiceAccountName)
     		assert.Equal(t, "my-ns", claims.ServiceAccountNamespace)
     	})
    +	t.Run("SSO+RBAC, Namespace delegation ON, no ssoNamespace match, Delegated", func(t *testing.T) {
    +		// Regression test: claims match a namespace-level rule but no
    +		// ssoNamespace rule. Previously this caused a nil pointer panic
    +		// because precedence(loginAccount) was called on nil.
    +		t.Setenv("SSO_DELEGATE_RBAC_TO_NAMESPACE", "true")
    +		ssoIf := &ssomocks.Interface{}
    +		ssoIf.On("Authorize", mock.Anything, mock.Anything).Return(&authTypes.Claims{Groups: []string{"user1-only-group"}}, nil)
    +		ssoIf.On("IsRBACEnabled").Return(true)
    +		g, err := NewGatekeeper(Modes{SSO: true}, clients, &rest.Config{Username: "my-username"}, ssoIf, clientForAuthorization, "my-ns", "my-ns", false, resourceCache)
    +		require.NoError(t, err)
    +		ctx, err := g.ContextWithRequest(x(logging.TestContext(t.Context()), "Bearer v2:whatever"), servertypes.NamespaceHolder("user1-ns"))
    +		require.NoError(t, err)
    +		claims := GetClaims(ctx)
    +		require.NotNil(t, claims)
    +		assert.Equal(t, "user1-only-sa", claims.ServiceAccountName)
    +		assert.Equal(t, "user1-ns", claims.ServiceAccountNamespace)
    +	})
     	t.Run("SSO+RBAC,precedence=0", func(t *testing.T) {
     		ssoIf := &ssomocks.Interface{}
     		ssoIf.On("Authorize", mock.Anything, mock.Anything).Return(&authTypes.Claims{Groups: []string{"other-group"}}, nil)
    

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

5

News mentions

0

No linked articles in our index yet.