VYPR
Medium severity4.3GHSA Advisory· Published Jan 31, 2025· Updated Apr 15, 2026

CVE-2024-11741

CVE-2024-11741

Description

Grafana is an open-source platform for monitoring and observability. The Grafana Alerting VictorOps integration was not properly protected and could be exposed to users with Viewer permission. Fixed in versions 11.5.0, 11.4.1, 11.3.3,  11.2.6, 11.1.11, 11.0.11 and 10.4.15

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Grafana Alerting VictorOps integration misconfiguration lets users with Viewer permission access the integration.

Vulnerability

Overview

The Grafana Alerting VictorOps integration had an authorization bypass vulnerability, classified as CVE-2024-11741 with a CVSS v3 score of 4.3 (Medium). The flaw allowed users with the Viewer role, who should have read-only access, to potentially access and interact with the VictorOps integration configuration [1]. This is due to improper access controls on the integration's API endpoints or configuration interfaces, which failed to enforce the principle of least privilege for lower-privileged users.

Attack

Vector and Exploitation

The vulnerability can be exploited by an authenticated attacker who already holds a Viewer permission in Grafana. The attacker would not need any additional privileges or specific network position to exploit the issue, as it depends on the application-level authorization checks. The exact attack surface appears to involve the ability to read or modify alerting receiver settings for the VictorOps integration [2], which could be done through Grafana's alerting API or UI.

Impact

Successful exploitation could allow a Viewer to view sensitive integration details (such as API keys or other secure fields) and potentially modify the integration configuration, leading to disruption of alerting workflows or interception of notifications. The vulnerability specifically affects the VictorOps integration, which is used to send alert notifications to the VictorOps incident management system [3].

Mitigation

The issue has been patched in Grafana versions 10.4.15, 11.0.11, 11.1.11, 11.2.6, 11.3.3, 11.4.1, and 11.5.0 [4]. Users are strongly advised to upgrade to one of the fixed versions. There is no mention of this CVE being listed in CISA's Known Exploited Vulnerabilities (KEV) catalog as of the publication date.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/grafana/grafanaGo
>= 11.4.0, < 11.4.111.4.1
github.com/grafana/grafanaGo
>= 11.3.0, < 11.3.311.3.3
github.com/grafana/grafanaGo
>= 11.2.0, < 11.2.611.2.6
github.com/grafana/grafanaGo
>= 11.1.0, < 11.1.1111.1.11
github.com/grafana/grafanaGo
>= 11.0.0, < 11.0.1111.0.11
github.com/grafana/grafanaGo
>= 1.9.2, < 10.4.1510.4.15
github.com/grafana/grafanaGo
< 0.0.0-20250129224826-70073427041e0.0.0-20250129224826-70073427041e
github.com/grafana/grafanaGo
>= 0.0.0, < 1.9.2-0.20250129224826-70073427041e1.9.2-0.20250129224826-70073427041e

Affected products

33

Patches

1
70073427041e

Alerting: k8s receivers api encrypt existing unencrypted secureFields on update (#99784)

https://github.com/grafana/grafanaYuri TseretyanJan 29, 2025via ghsa
12 files changed · +74 12
  • go.mod+1 1 modified
    @@ -69,7 +69,7 @@ require (
     	github.com/googleapis/gax-go/v2 v2.14.1 // @grafana/grafana-backend-group
     	github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group
     	github.com/gorilla/websocket v1.5.3 // @grafana/grafana-app-platform-squad
    -	github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce // @grafana/alerting-backend
    +	github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a // @grafana/alerting-backend
     	github.com/grafana/authlib v0.0.0-20250123104008-e99947858901 // @grafana/identity-access-team
     	github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c // @grafana/identity-access-team
     	github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics
    
  • go.sum+2 2 modified
    @@ -1498,8 +1498,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg
     github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
     github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
     github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
    -github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce h1:lilqLsOGzo+0SuyXjaN5XRVJbnkJRB0bXMoIlYHTIPE=
    -github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
    +github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a h1:44E+I3EPdh/W02Uyfyig86EJKPjvzcF3y0A+FEi1fBk=
    +github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
     github.com/grafana/authlib v0.0.0-20250123104008-e99947858901 h1:nqV1YrtX+ZG+EYB5dcmFMWhg2Y038OMaAHAADbOC9RA=
     github.com/grafana/authlib v0.0.0-20250123104008-e99947858901/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
     github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c h1:b0sPDtt33uFdmvUJjSCld3kwE2E49dUvevuUDSJsEuo=
    
  • go.work.sum+1 0 modified
    @@ -1502,6 +1502,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
     github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
     github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
     github.com/grafana/alerting v0.0.0-20250115195200-209e052dba64/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
    +github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
     github.com/grafana/authlib v0.0.0-20250120144156-d6737a7dc8f5/go.mod h1:V63rh3udd7sqXJeaG+nGUmViwVnM/bY6t8U9Tols2GU=
     github.com/grafana/authlib v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
     github.com/grafana/authlib/types v0.0.0-20250120144156-d6737a7dc8f5/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
    
  • pkg/services/ngalert/api/tooling/definitions/contact_points.go+1 1 modified
    @@ -268,7 +268,7 @@ type ThreemaIntegration struct {
     type VictoropsIntegration struct {
     	DisableResolveMessage *bool `json:"-" yaml:"-" hcl:"disable_resolve_message"`
     
    -	URL string `json:"url" yaml:"url" hcl:"url"`
    +	URL Secret `json:"url" yaml:"url" hcl:"url"`
     
     	MessageType *string `json:"messageType,omitempty" yaml:"messageType,omitempty" hcl:"message_type"`
     	Title       *string `json:"title,omitempty" yaml:"title,omitempty" hcl:"title"`
    
  • pkg/services/ngalert/notifier/channels_config/available_channels.go+1 0 modified
    @@ -388,6 +388,7 @@ func GetAvailableNotifiers() []*NotifierPlugin {
     					Placeholder:  "VictorOps url",
     					PropertyName: "url",
     					Required:     true,
    +					Secure:       true,
     				},
     				{ // New in 8.0.
     					Label:        "Message Type",
    
  • pkg/services/ngalert/notifier/channels_config/available_channels_test.go+1 1 modified
    @@ -15,7 +15,7 @@ func TestGetSecretKeysForContactPointType(t *testing.T) {
     		{receiverType: "kafka", expectedSecretFields: []string{"password"}},
     		{receiverType: "email", expectedSecretFields: []string{}},
     		{receiverType: "pagerduty", expectedSecretFields: []string{"integrationKey"}},
    -		{receiverType: "victorops", expectedSecretFields: []string{}},
    +		{receiverType: "victorops", expectedSecretFields: []string{"url"}},
     		{receiverType: "oncall", expectedSecretFields: []string{"password", "authorization_credentials"}},
     		{receiverType: "pushover", expectedSecretFields: []string{"apiToken", "userKey"}},
     		{receiverType: "slack", expectedSecretFields: []string{"token", "url"}},
    
  • pkg/services/ngalert/notifier/receiver_svc.go+8 0 modified
    @@ -485,6 +485,14 @@ func (rs *ReceiverService) UpdateReceiver(ctx context.Context, r *models.Receive
     		return nil, err
     	}
     
    +	// We re-encrypt the existing receiver to ensure any unencrypted secure fields that are correctly encrypted, note this should NOT re-encrypt secure fields that are already encrypted.
    +	// This is rare, but can happen if a receiver is created with unencrypted secure fields and then the secure option is added later.
    +	// Preferably, this would be handled by receiver config versions and migrations but for now this is a good safety net.
    +	err = existing.Encrypt(rs.encryptor(ctx))
    +	if err != nil {
    +		return nil, err
    +	}
    +
     	span.AddEvent("Loaded current receiver", trace.WithAttributes(
     		attribute.String("concurrency_token", revision.ConcurrencyToken),
     		attribute.String("receiver", existing.Name),
    
  • pkg/services/ngalert/notifier/receiver_svc_test.go+53 1 modified
    @@ -583,6 +583,44 @@ func TestReceiverService_Update(t *testing.T) {
     			), rm.Encrypted(models.Base64Enrypt)),
     			expectedProvenances: map[string]models.Provenance{slackIntegration.UID: models.ProvenanceNone},
     		},
    +		{
    +			name: "encrypts previously unencrypted secure fields",
    +			user: writer,
    +			receiver: models.CopyReceiverWith(baseReceiver, rm.WithIntegrations(
    +				models.CopyIntegrationWith(slackIntegration, im.AddSetting("token", "unencryptedValue"))),
    +			),
    +			existing: util.Pointer(models.CopyReceiverWith(baseReceiver, rm.WithIntegrations(
    +				models.CopyIntegrationWith(slackIntegration,
    +					im.AddSetting("token", "unencryptedValue"), // This will get encrypted.
    +				),
    +			))),
    +			expectedUpdate: models.CopyReceiverWith(baseReceiver, rm.WithIntegrations(
    +				models.CopyIntegrationWith(slackIntegration,
    +					im.AddSecureSetting("token", "dW5lbmNyeXB0ZWRWYWx1ZQ==")),
    +			), rm.Encrypted(models.Base64Enrypt)),
    +			expectedProvenances: map[string]models.Provenance{slackIntegration.UID: models.ProvenanceNone},
    +		},
    +		{
    +			// This test is important for covering the rare case when an existing field is marked as secure.
    +			// The UI will receive the field as secure and, if unchanged, will pass it back on update as a secureField instead of a Setting.
    +			name: "encrypts previously unencrypted secure fields when passed in as secureFields",
    +			user: writer,
    +			receiver: models.CopyReceiverWith(baseReceiver, rm.WithIntegrations(
    +				models.CopyIntegrationWith(slackIntegration, im.AddSetting("newField", "newValue"))),
    +			),
    +			secureFields: map[string][]string{slackIntegration.UID: {"token"}},
    +			existing: util.Pointer(models.CopyReceiverWith(baseReceiver, rm.WithIntegrations(
    +				models.CopyIntegrationWith(slackIntegration,
    +					im.AddSetting("token", "unencryptedValue"), // This will get encrypted.
    +				),
    +			))),
    +			expectedUpdate: models.CopyReceiverWith(baseReceiver, rm.WithIntegrations(
    +				models.CopyIntegrationWith(slackIntegration,
    +					im.AddSetting("newField", "newValue"),
    +					im.AddSecureSetting("token", "dW5lbmNyeXB0ZWRWYWx1ZQ==")),
    +			), rm.Encrypted(models.Base64Enrypt)),
    +			expectedProvenances: map[string]models.Provenance{slackIntegration.UID: models.ProvenanceNone},
    +		},
     		{
     			name: "doesn't copy existing unsecure fields",
     			user: writer,
    @@ -684,8 +722,22 @@ func TestReceiverService_Update(t *testing.T) {
     			sut := createReceiverServiceSut(t, &secretsService)
     
     			if tc.existing != nil {
    -				created, err := sut.CreateReceiver(context.Background(), tc.existing, tc.user.GetOrgID(), tc.user)
    +				// Create route after receivers as they will be referenced.
    +				revision, err := sut.cfgStore.Get(context.Background(), tc.user.GetOrgID())
    +				require.NoError(t, err)
    +				result, err := revision.CreateReceiver(tc.existing)
    +				require.NoError(t, err)
    +
    +				created, err := PostableApiReceiverToReceiver(result, tc.existing.Provenance)
     				require.NoError(t, err)
    +				err = sut.cfgStore.Save(context.Background(), revision, tc.user.GetOrgID())
    +				require.NoError(t, err)
    +
    +				for _, integration := range created.Integrations {
    +					target := definitions.EmbeddedContactPoint{UID: integration.UID}
    +					err = sut.provisioningStore.SetProvenance(context.Background(), &target, tc.user.GetOrgID(), created.Provenance)
    +					require.NoError(t, err)
    +				}
     
     				if tc.version == "" {
     					tc.version = created.Version
    
  • pkg/storage/unified/apistore/go.mod+1 1 modified
    @@ -170,7 +170,7 @@ require (
     	github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
     	github.com/googleapis/gax-go/v2 v2.14.1 // indirect
     	github.com/gorilla/mux v1.8.1 // indirect
    -	github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce // indirect
    +	github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a // indirect
     	github.com/grafana/authlib v0.0.0-20250123104008-e99947858901 // indirect
     	github.com/grafana/dataplane/sdata v0.0.9 // indirect
     	github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 // indirect
    
  • pkg/storage/unified/apistore/go.sum+2 2 modified
    @@ -547,8 +547,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
     github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
     github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
     github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
    -github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce h1:lilqLsOGzo+0SuyXjaN5XRVJbnkJRB0bXMoIlYHTIPE=
    -github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
    +github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a h1:44E+I3EPdh/W02Uyfyig86EJKPjvzcF3y0A+FEi1fBk=
    +github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
     github.com/grafana/authlib v0.0.0-20250123104008-e99947858901 h1:nqV1YrtX+ZG+EYB5dcmFMWhg2Y038OMaAHAADbOC9RA=
     github.com/grafana/authlib v0.0.0-20250123104008-e99947858901/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
     github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c h1:b0sPDtt33uFdmvUJjSCld3kwE2E49dUvevuUDSJsEuo=
    
  • pkg/storage/unified/resource/go.mod+1 1 modified
    @@ -115,7 +115,7 @@ require (
     	github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
     	github.com/googleapis/gax-go/v2 v2.14.1 // indirect
     	github.com/gorilla/mux v1.8.1 // indirect
    -	github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce // indirect
    +	github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a // indirect
     	github.com/grafana/dataplane/sdata v0.0.9 // indirect
     	github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect
     	github.com/grafana/grafana-aws-sdk v0.31.5 // indirect
    
  • pkg/storage/unified/resource/go.sum+2 2 modified
    @@ -403,8 +403,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
     github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
     github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
     github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
    -github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce h1:lilqLsOGzo+0SuyXjaN5XRVJbnkJRB0bXMoIlYHTIPE=
    -github.com/grafana/alerting v0.0.0-20250128163937-4446935bbcce/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
    +github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a h1:44E+I3EPdh/W02Uyfyig86EJKPjvzcF3y0A+FEi1fBk=
    +github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
     github.com/grafana/authlib v0.0.0-20250123104008-e99947858901 h1:nqV1YrtX+ZG+EYB5dcmFMWhg2Y038OMaAHAADbOC9RA=
     github.com/grafana/authlib v0.0.0-20250123104008-e99947858901/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
     github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c h1:b0sPDtt33uFdmvUJjSCld3kwE2E49dUvevuUDSJsEuo=
    

Vulnerability mechanics

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

References

8

News mentions

0

No linked articles in our index yet.