VYPR
Moderate severityNVD Advisory· Published Sep 3, 2025· Updated Nov 4, 2025

CVE-2025-58460

CVE-2025-58460

Description

A missing permission check in Jenkins OpenTelemetry Plugin 3.1543.v8446b_92b_cd64 and earlier allows attackers with Overall/Read permission to connect to an attacker-specified URL using attacker-specified credentials IDs obtained through another method, capturing credentials stored in Jenkins.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
io.jenkins.plugins:opentelemetryMaven
< 3.1543.1545.vf5a3.1543.1545.vf5a

Affected products

1

Patches

1
f5a4ec123769

[SECURITY-3602]

https://github.com/jenkinsci/opentelemetry-pluginIvan Fernandez CalvoAug 26, 2025via ghsa
3 files changed · +36 12
  • src/main/java/io/jenkins/plugins/opentelemetry/backend/elastic/ElasticLogsBackendWithJenkinsVisualization.java+20 8 modified
    @@ -129,6 +129,9 @@ public String getDisplayName() {
     
             @RequirePOST
             public FormValidation doCheckElasticsearchUrl(@QueryParameter("elasticsearchUrl") String url) {
    +            if (!isAuthorized()) {
    +                return FormValidation.error("You do not have permission to configure this setting.");
    +            }
                 if (StringUtils.isEmpty(url)) {
                     return FormValidation.ok();
                 }
    @@ -141,24 +144,22 @@ public FormValidation doCheckElasticsearchUrl(@QueryParameter("elasticsearchUrl"
             }
     
             @RequirePOST
    -        public ListBoxModel doFillElasticsearchCredentialsIdItems(Item context,
    +        public ListBoxModel doFillElasticsearchCredentialsIdItems(
                     @QueryParameter String elasticsearchCredentialsId) {
    -            if (context == null && !Jenkins.get().hasPermission(Jenkins.ADMINISTER)
    -                    || context != null && !context.hasPermission(Item.CONFIGURE)) {
    +            if (!isAuthorized()) {
                     return new StandardListBoxModel();
                 }
     
                 return new StandardListBoxModel().includeEmptyValue()
    -                    .includeAs(ACL.SYSTEM2, context, StandardUsernameCredentials.class)
    +                    .includeAs(ACL.SYSTEM2, (Item) null, StandardUsernameCredentials.class)
                         .includeCurrentValue(elasticsearchCredentialsId);
             }
     
             @RequirePOST
    -        public FormValidation doCheckElasticsearchCredentialsId(Item context,
    +        public FormValidation doCheckElasticsearchCredentialsId(
                     @QueryParameter String elasticsearchCredentialsId) {
    -            if (context == null && !Jenkins.get().hasPermission(Jenkins.ADMINISTER)
    -                    || context != null && !context.hasPermission(Item.CONFIGURE)) {
    -                return FormValidation.ok();
    +            if (!isAuthorized()) {
    +                return FormValidation.error("You do not have permission to configure this setting.");
                 }
     
                 if (elasticsearchCredentialsId == null || elasticsearchCredentialsId.isEmpty()) {
    @@ -175,6 +176,9 @@ public FormValidation doCheckElasticsearchCredentialsId(Item context,
             @RequirePOST
             public FormValidation doValidate(@QueryParameter String elasticsearchUrl,
                     @QueryParameter boolean disableSslVerifications, @QueryParameter String elasticsearchCredentialsId) {
    +            if (!isAuthorized()) {
    +                return FormValidation.error("You do not have permission to configure this setting.");
    +            }
                 FormValidation elasticsearchUrlValidation = doCheckElasticsearchUrl(elasticsearchUrl);
                 if (elasticsearchUrlValidation.kind != FormValidation.Kind.OK) {
                     return elasticsearchUrlValidation;
    @@ -193,5 +197,13 @@ public FormValidation doValidate(@QueryParameter String elasticsearchUrl,
                     return FormValidation.error(e, e.getMessage());
                 }
             }
    +
    +        /**
    +         * Checks if the user has permission to configure the backend.
    +         * @return true if the user is authorized, false otherwise
    +         */
    +        private boolean isAuthorized() {
    +            return Jenkins.get().hasPermission(Jenkins.ADMINISTER);
    +        }
         }
     }
    
  • src/test/java/io/jenkins/plugins/opentelemetry/backend/elastic/ElasticsearchBackendITTest.java+3 3 modified
    @@ -75,7 +75,7 @@ public void testDoFillCredentialsIdItems(JenkinsConfiguredWithCodeRule j) {
             ElasticLogsBackendWithJenkinsVisualization visualization = elasticStack.getElasticStackConfiguration();
             ElasticLogsBackendWithJenkinsVisualization.DescriptorImpl visDescriptor = (ElasticLogsBackendWithJenkinsVisualization.DescriptorImpl) visualization
                     .getDescriptor();
    -        assertFalse(visDescriptor.doFillElasticsearchCredentialsIdItems(null, ElasticStack.CRED_ID).isEmpty());
    +        assertFalse(visDescriptor.doFillElasticsearchCredentialsIdItems(ElasticStack.CRED_ID).isEmpty());
         }
     
         @Test
    @@ -86,8 +86,8 @@ public void testDoCheckCredentialsId(JenkinsConfiguredWithCodeRule j) {
             ElasticLogsBackendWithJenkinsVisualization.DescriptorImpl visDescriptor = (ElasticLogsBackendWithJenkinsVisualization.DescriptorImpl) visualization
                     .getDescriptor();
             assertEquals(FormValidation.Kind.OK,
    -                visDescriptor.doCheckElasticsearchCredentialsId(null, ElasticStack.CRED_ID).kind);
    -        assertEquals(FormValidation.Kind.ERROR, visDescriptor.doCheckElasticsearchCredentialsId(null, "foo").kind);
    +                visDescriptor.doCheckElasticsearchCredentialsId(ElasticStack.CRED_ID).kind);
    +        assertEquals(FormValidation.Kind.ERROR, visDescriptor.doCheckElasticsearchCredentialsId("foo").kind);
         }
     
         private void waitForLogs(WorkflowRun run) throws InterruptedException {
    
  • src/test/java/io/jenkins/plugins/opentelemetry/job/log/ElasticStackConfigurationFormTest.java+13 1 modified
    @@ -7,12 +7,24 @@
     import hudson.util.FormValidation;
     import io.jenkins.plugins.opentelemetry.backend.ElasticBackend;
     import io.jenkins.plugins.opentelemetry.backend.elastic.ElasticLogsBackendWithJenkinsVisualization;
    -import org.junit.Test;
    +import org.junit.jupiter.api.BeforeEach;
    +import org.junit.jupiter.api.Test;
    +import org.jvnet.hudson.test.JenkinsRule;
    +import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
     
     import static junit.framework.TestCase.assertEquals;
     
    +@WithJenkins
     public class ElasticStackConfigurationFormTest {
     
    +    @SuppressWarnings("unused")
    +    private JenkinsRule r;
    +
    +    @BeforeEach
    +    public void setUp(JenkinsRule r) {
    +        this.r = r;
    +    }
    +
         @Test
         public void testDoCheckKibanaUrl() {
             ElasticBackend.DescriptorImpl config = new ElasticBackend.DescriptorImpl();
    

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

News mentions

0

No linked articles in our index yet.