Medium severity5.5NVD Advisory· Published May 26, 2025· Updated Apr 15, 2026
CVE-2025-4057
CVE-2025-4057
Description
A flaw was found in ActiveMQ Artemis. The password generated by activemq-artemis-operator does not regenerate between separated CR dependencies.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/arkmq-org/activemq-artemis-operatorGo | <= 0.0.0-20250418141202-b262048e6a75 | — |
Patches
1d3482fab6d00[#1130] Remove global environment defaults
https://github.com/arkmq-org/activemq-artemis-operatorDomenico Francesco BruscinoApr 8, 2025via ghsa
4 files changed · +121 −69
controllers/activemqartemis_controller_test.go+98 −1 modified@@ -1069,7 +1069,12 @@ var _ = Describe("artemis controller", func() { Context("broker resource tracking", Label("broker-resource-tracking-context"), func() { It("default user credential secret", func() { By("deploy a broker") - brokerCr, _ := DeployCustomBroker(defaultNamespace, nil) + brokerCr, createdBrokerCr := DeployCustomBroker(defaultNamespace, nil) + + var amqUser []byte + var amqPassword []byte + var amqClusterUser []byte + var amqClusterPassword []byte By("checking the default credential secret created") credSecretKey := types.NamespacedName{ @@ -1081,7 +1086,18 @@ var _ = Describe("artemis controller", func() { ssKey := types.NamespacedName{Name: namer.CrToSS(brokerCr.Name), Namespace: defaultNamespace} Eventually(func(g Gomega) { g.Expect(k8sClient.Get(ctx, credSecretKey, credSecret)).Should(Succeed()) + + var amqKeyFound bool g.Expect(len(credSecret.Data)).To(Equal(4)) + amqUser, amqKeyFound = credSecret.Data["AMQ_USER"] + g.Expect(amqKeyFound).Should(BeTrue()) + amqPassword, amqKeyFound = credSecret.Data["AMQ_PASSWORD"] + g.Expect(amqKeyFound).Should(BeTrue()) + amqClusterUser, amqKeyFound = credSecret.Data["AMQ_CLUSTER_USER"] + g.Expect(amqKeyFound).Should(BeTrue()) + amqClusterPassword, amqKeyFound = credSecret.Data["AMQ_CLUSTER_PASSWORD"] + g.Expect(amqKeyFound).Should(BeTrue()) + g.Expect(len(credSecret.OwnerReferences) > 0).Should(BeTrue()) ownerFound := false for _, oref := range credSecret.OwnerReferences { @@ -1128,6 +1144,87 @@ var _ = Describe("artemis controller", func() { }, timeout, interval).Should(Succeed()) + By("update the broker to trigger reconcile") + brokerKey := types.NamespacedName{ + Name: brokerCr.Name, + Namespace: defaultNamespace, + } + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, brokerKey, createdBrokerCr)).Should(Succeed()) + createdBrokerCr.Spec.Env = append(createdBrokerCr.Spec.Env, corev1.EnvVar{Name: "NEW_VAR", Value: "NEW_VALUE"}) + g.Expect(k8sClient.Update(ctx, createdBrokerCr)).Should(Succeed()) + }, timeout, interval).Should(Succeed()) + + newCreatedBrokerCr := brokerv1beta1.ActiveMQArtemis{} + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, brokerKey, &newCreatedBrokerCr)).Should(Succeed()) + g.Expect(len(newCreatedBrokerCr.Spec.Env)).To(Equal(1)) + g.Expect(newCreatedBrokerCr.Spec.Env[0].Name).To(Equal("NEW_VAR")) + g.Expect(newCreatedBrokerCr.Spec.Env[0].Value).To(Equal("NEW_VALUE")) + }, timeout, interval).Should(Succeed()) + + newSS := &appsv1.StatefulSet{} + credSecretAfterRecon := &corev1.Secret{} + + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, ssKey, newSS)).Should(Succeed()) + + container := newSS.Spec.Template.Spec.Containers[0] + newVarFound := false + for _, envVar := range container.Env { + if envVar.Name == "NEW_VAR" { + newVarFound = true + g.Expect(envVar.Value).To(Equal("NEW_VALUE")) + } + } + g.Expect(newVarFound).To(BeTrue()) + + initContainer := newSS.Spec.Template.Spec.InitContainers[0] + userFound := false + passwordFound := false + clusterUserFound := false + clusterPasswordFound := false + for _, envVar := range initContainer.Env { + if envVar.Name == "AMQ_USER" { + userFound = true + g.Expect(envVar.ValueFrom.SecretKeyRef.Name).To(Equal(credSecretKey.Name)) + g.Expect(envVar.ValueFrom.SecretKeyRef.Key).To(Equal("AMQ_USER")) + } else if envVar.Name == "AMQ_PASSWORD" { + passwordFound = true + g.Expect(envVar.ValueFrom.SecretKeyRef.Name).To(Equal(credSecretKey.Name)) + g.Expect(envVar.ValueFrom.SecretKeyRef.Key).To(Equal("AMQ_PASSWORD")) + } else if envVar.Name == "AMQ_CLUSTER_USER" { + clusterUserFound = true + g.Expect(envVar.ValueFrom.SecretKeyRef.Name).To(Equal(credSecretKey.Name)) + g.Expect(envVar.ValueFrom.SecretKeyRef.Key).To(Equal("AMQ_CLUSTER_USER")) + } else if envVar.Name == "AMQ_CLUSTER_PASSWORD" { + clusterPasswordFound = true + g.Expect(envVar.ValueFrom.SecretKeyRef.Name).To(Equal(credSecretKey.Name)) + g.Expect(envVar.ValueFrom.SecretKeyRef.Key).To(Equal("AMQ_CLUSTER_PASSWORD")) + } + } + g.Expect(userFound).To(BeTrue()) + g.Expect(passwordFound).To(BeTrue()) + g.Expect(clusterUserFound).To(BeTrue()) + g.Expect(clusterPasswordFound).To(BeTrue()) + + g.Expect(k8sClient.Get(ctx, credSecretKey, credSecretAfterRecon)).Should(Succeed()) + g.Expect(credSecretAfterRecon.Data["AMQ_USER"]).To(Equal(amqUser)) + g.Expect(credSecretAfterRecon.Data["AMQ_PASSWORD"]).To(Equal(amqPassword)) + g.Expect(credSecretAfterRecon.Data["AMQ_CLUSTER_USER"]).To(Equal(amqClusterUser)) + g.Expect(credSecretAfterRecon.Data["AMQ_CLUSTER_PASSWORD"]).To(Equal(amqClusterPassword)) + + g.Expect(len(credSecretAfterRecon.OwnerReferences) > 0).Should(BeTrue()) + ownerFound := false + for _, oref := range credSecretAfterRecon.OwnerReferences { + if oref.Kind == artemisGvk.Kind && oref.Name == brokerCr.Name { + ownerFound = true + break + } + } + g.Expect(ownerFound).To(BeTrue()) + }, timeout, interval).Should(Succeed()) + CleanResource(brokerCr, brokerCr.Name, defaultNamespace) })
controllers/activemqartemis_reconciler.go+5 −6 modified@@ -29,6 +29,7 @@ import ( "github.com/arkmq-org/activemq-artemis-operator/pkg/utils/cr2jinja2" "github.com/arkmq-org/activemq-artemis-operator/pkg/utils/jolokia_client" "github.com/arkmq-org/activemq-artemis-operator/pkg/utils/namer" + "github.com/arkmq-org/activemq-artemis-operator/pkg/utils/random" "github.com/arkmq-org/activemq-artemis-operator/version" "github.com/go-logr/logr" "github.com/pkg/errors" @@ -338,7 +339,7 @@ func (reconciler *ActiveMQArtemisReconcilerImpl) ProcessCredentials(customResour adminUser.Value = amqUserEnvVar.Value } if adminUser.Value == "" { - adminUser.Value = environments.Defaults.AMQ_USER + adminUser.Value = random.GenerateRandomString(8) adminUser.AutoGen = true } } @@ -350,18 +351,18 @@ func (reconciler *ActiveMQArtemisReconcilerImpl) ProcessCredentials(customResour adminPassword.Value = amqPasswordEnvVar.Value } if adminPassword.Value == "" { - adminPassword.Value = environments.Defaults.AMQ_PASSWORD + adminPassword.Value = random.GenerateRandomString(8) adminPassword.AutoGen = true } } envVars["AMQ_PASSWORD"] = adminPassword envVars["AMQ_CLUSTER_USER"] = ValueInfo{ - Value: environments.GLOBAL_AMQ_CLUSTER_USER, + Value: random.GenerateRandomString(8), AutoGen: true, } envVars["AMQ_CLUSTER_PASSWORD"] = ValueInfo{ - Value: environments.GLOBAL_AMQ_CLUSTER_PASSWORD, + Value: random.GenerateRandomString(8), AutoGen: true, } @@ -510,8 +511,6 @@ func (reconciler *ActiveMQArtemisReconcilerImpl) syncMessageMigration(customReso ssNames := make(map[string]string) ssNames["CRNAMESPACE"] = customResource.Namespace ssNames["CRNAME"] = customResource.Name - ssNames["CLUSTERUSER"] = environments.GLOBAL_AMQ_CLUSTER_USER - ssNames["CLUSTERPASS"] = environments.GLOBAL_AMQ_CLUSTER_PASSWORD ssNames["HEADLESSSVCNAMEVALUE"] = namer.SvcHeadlessNameBuilder.Name() ssNames["PINGSVCNAMEVALUE"] = namer.SvcPingNameBuilder.Name() ssNames["SERVICE_ACCOUNT"] = os.Getenv("SERVICE_ACCOUNT")
pkg/draincontroller/controller.go+18 −29 modified@@ -49,8 +49,6 @@ import ( "strings" rbacutil "github.com/arkmq-org/activemq-artemis-operator/pkg/rbac" - "github.com/arkmq-org/activemq-artemis-operator/pkg/resources" - "github.com/arkmq-org/activemq-artemis-operator/pkg/resources/secrets" "github.com/arkmq-org/activemq-artemis-operator/pkg/utils/namer" "github.com/arkmq-org/activemq-artemis-operator/pkg/utils/selectors" "k8s.io/apimachinery/pkg/labels" @@ -736,30 +734,6 @@ func (c *Controller) GetStopCh() *chan struct{} { return &c.stopCh } -func (c *Controller) getClusterCredentials(namespace string, ssNames map[string]string) (string, string) { - - secretName := ssNames["AMQ_CREDENTIALS_SECRET_NAME"] - - namespacedName := types.NamespacedName{ - Name: secretName, - Namespace: namespace, - } - stringDataMap := make(map[string]string) - stringDataMap["AMQ_CLUSTER_USER"] = "" - stringDataMap["AMQ_CLUSTER_PASSWORD"] = "" - - secretDefinition := secrets.NewSecret(namespacedName, stringDataMap, c.ssLabels) - - c.log.V(2).Info("Try retrieving cluster credentials from secret", "secret", namespacedName) - if err := resources.Retrieve(namespacedName, c.client, secretDefinition); err != nil { - c.log.V(2).Info("Failed to retrieve cluster credentials from secret, using defaults", "err", err) - return ssNames["CLUSTERUSER"], ssNames["CLUSTERPASS"] - } else { - c.log.V(2).Info("retrieved cluster credential from existing secret") - return string(secretDefinition.Data["AMQ_CLUSTER_USER"]), string(secretDefinition.Data["AMQ_CLUSTER_PASSWORD"]) - } -} - func (c *Controller) newPod(sts *appsv1.StatefulSet, ordinal int) (*corev1.Pod, error) { ssNamesKey := types.NamespacedName{ @@ -778,10 +752,7 @@ func (c *Controller) newPod(sts *appsv1.StatefulSet, ordinal int) (*corev1.Pod, //podTemplateJson := sts.Annotations[AnnotationDrainerPodTemplate] //TODO: Remove this blatant hack podTemplateJson := globalPodTemplateJson - clusterUser, clusterPassword := c.getClusterCredentials(sts.Namespace, ssNames) podTemplateJson = strings.Replace(podTemplateJson, "CRNAME", ssNames["CRNAME"], -1) - podTemplateJson = strings.Replace(podTemplateJson, "CLUSTERUSER", clusterUser, 1) - podTemplateJson = strings.Replace(podTemplateJson, "CLUSTERPASS", clusterPassword, 1) podTemplateJson = strings.Replace(podTemplateJson, "HEADLESSSVCNAMEVALUE", ssNames["HEADLESSSVCNAMEVALUE"], 1) podTemplateJson = strings.Replace(podTemplateJson, "PINGSVCNAMEVALUE", ssNames["PINGSVCNAMEVALUE"], 1) @@ -856,6 +827,24 @@ func (c *Controller) newPod(sts *appsv1.StatefulSet, ordinal int) (*corev1.Pod, } pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, drainerHost) + for i := 0; i < len(pod.Spec.Containers[0].Env); i++ { + if pod.Spec.Containers[0].Env[i].Name == "AMQ_CLUSTER_USER" || + pod.Spec.Containers[0].Env[i].Name == "AMQ_CLUSTER_PASSWORD" { + envVarSource := &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: ssNames["AMQ_CREDENTIALS_SECRET_NAME"], + }, + Key: pod.Spec.Containers[0].Env[i].Name, + Optional: nil, + }, + } + pod.Spec.Containers[0].Env[i].Value = "" + pod.Spec.Containers[0].Env[i].ValueFrom = envVarSource + } + + } + pod.Spec.SecurityContext = sts.Spec.Template.Spec.SecurityContext for i := 0; i < len(pod.Spec.Containers); i++ { pod.Spec.Containers[i].SecurityContext = sts.Spec.Template.Spec.Containers[0].SecurityContext
pkg/resources/environments/environment.go+0 −33 modified@@ -3,7 +3,6 @@ package environments import ( "strconv" - "github.com/arkmq-org/activemq-artemis-operator/pkg/utils/random" corev1 "k8s.io/api/core/v1" ) @@ -12,38 +11,6 @@ const ( NameEnvVarDefaultValue = "amq-broker" ) -// TODO: Remove this blatant hack -var GLOBAL_AMQ_CLUSTER_USER string = "" -var GLOBAL_AMQ_CLUSTER_PASSWORD string = "" - -type defaults struct { - AMQ_USER string - AMQ_PASSWORD string - AMQ_CLUSTER_USER string - AMQ_CLUSTER_PASSWORD string -} - -var Defaults defaults - -func init() { - if "" == Defaults.AMQ_USER { - Defaults.AMQ_USER = random.GenerateRandomString(8) - } - if "" == Defaults.AMQ_PASSWORD { - Defaults.AMQ_PASSWORD = random.GenerateRandomString(8) - } - if "" == Defaults.AMQ_CLUSTER_USER { - Defaults.AMQ_CLUSTER_USER = random.GenerateRandomString(8) - // TODO: remove this hack - GLOBAL_AMQ_CLUSTER_USER = Defaults.AMQ_CLUSTER_USER - } - if "" == Defaults.AMQ_CLUSTER_PASSWORD { - Defaults.AMQ_CLUSTER_PASSWORD = random.GenerateRandomString(8) - // TODO: remove this hack - GLOBAL_AMQ_CLUSTER_PASSWORD = Defaults.AMQ_CLUSTER_PASSWORD - } -} - func ResolveBrokerNameFromEnvs(envs []corev1.EnvVar, defaultValue string) string { if len(envs) > 0 { for _, v := range envs {
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
9- github.com/advisories/GHSA-q5q7-8x6x-hcg2ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-4057ghsaADVISORY
- access.redhat.com/errata/RHSA-2025:12355nvdWEB
- access.redhat.com/errata/RHSA-2025:12473nvdWEB
- access.redhat.com/errata/RHSA-2025:8147nvdWEB
- access.redhat.com/security/cve/CVE-2025-4057nvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- github.com/arkmq-org/activemq-artemis-operator/commit/d3482fab6d0060794226c9e5a6fa67d209abc35anvdWEB
- github.com/arkmq-org/activemq-artemis-operator/issues/1130nvdWEB
News mentions
0No linked articles in our index yet.