CVE-2023-50769
Description
Missing permission checks in Jenkins Nexus Platform Plugin allow attackers with Overall/Read to exfiltrate stored credentials by connecting to an attacker-controlled server.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Missing permission checks in Jenkins Nexus Platform Plugin allow attackers with Overall/Read to exfiltrate stored credentials by connecting to an attacker-controlled server.
CVE-2023-50769: Missing Permission Checks in Nexus Platform Plugin
The Jenkins Nexus Platform Plugin versions 3.18.0-03 and earlier contain missing permission checks in HTTP endpoints handling configuration validation [1][3]. Specifically, the doCheckDisplayName and doCheckId methods lack authorization checks, allowing any user with Overall/Read permission to trigger connections to an attacker-specified HTTP server [1]. This vulnerability is distinct from CSRF, but the fix also adds CSRF protection [4].
Attackers who have obtained credentials IDs through another means (e.g., another vulnerability or information disclosure) can exploit this by crafting a request that uses those IDs to connect to a server under their control [1][2]. The plugin does not validate that the requester has permission to use the specified credentials, enabling exfiltration of stored credentials.
Successful exploitation allows an attacker to capture Jenkins credentials, potentially leading to unauthorized access to connected systems [1][3]. The captured credentials can be used to further compromise the Jenkins environment or connected services.
The vulnerability is fixed in Nexus Platform Plugin version 3.18.1-01, released on December 13, 2023 [1][2]. Administrators should update immediately. No workarounds have been announced.
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.
| Package | Affected versions | Patched versions |
|---|---|---|
org.sonatype.nexus.ci:nexus-jenkins-pluginMaven | < 3.18.1-01 | 3.18.1-01 |
Affected products
2- Range: 0
Patches
11d5e1e9e457aAdd protection from CSRF (#291)
4 files changed · +20 −1
pom.xml+1 −1 modified@@ -85,7 +85,7 @@ <enforcer.skip>true</enforcer.skip> <!-- TODO numerous requireUpperBoundDeps, some probably indicative of real problems --> <jvnet-localizer-plugin.version>1.23</jvnet-localizer-plugin.version> <forkCount>1</forkCount> - <nexus-platform-api.version>4.3.1-01</nexus-platform-api.version> + <nexus-platform-api.version>4.3.2-01</nexus-platform-api.version> <buildsupport.version>36</buildsupport.version> <buildsupport.license-maven-plugin.version>4.1</buildsupport.license-maven-plugin.version>
src/main/java/org/sonatype/nexus/ci/config/NxiqConfiguration.groovy+9 −0 modified@@ -24,6 +24,7 @@ import hudson.util.ListBoxModel import jenkins.model.Jenkins import org.kohsuke.stapler.DataBoundConstructor import org.kohsuke.stapler.QueryParameter +import org.kohsuke.stapler.verb.POST class NxiqConfiguration implements Describable<NxiqConfiguration> @@ -83,7 +84,9 @@ class NxiqConfiguration Messages.NxiqConfiguration_DisplayName() } + @POST FormValidation doCheckDisplayName(@QueryParameter String value, @QueryParameter String internalId) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER) def globalConfigurations = GlobalNexusConfiguration.globalNexusConfiguration for (NxiqConfiguration config : globalConfigurations.iqConfigs) { if (config.internalId != internalId && config.displayName == value) { @@ -93,7 +96,9 @@ class NxiqConfiguration return FormUtil.validateNotEmpty(value, 'Display Name is required') } + @POST FormValidation doCheckId(@QueryParameter String value, @QueryParameter String internalId) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER) def globalConfigurations = GlobalNexusConfiguration.globalNexusConfiguration for (NxiqConfiguration config : globalConfigurations.iqConfigs) { if (config.internalId != internalId && config.id == value) { @@ -108,7 +113,9 @@ class NxiqConfiguration } @SuppressWarnings('unused') + @POST FormValidation doCheckServerUrl(@QueryParameter String value) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER) def validation = FormUtil.validateUrl(value) if (validation.kind == Kind.OK) { validation = FormUtil.validateNotEmpty(value, Messages.Configuration_ServerUrlRequired()) @@ -123,10 +130,12 @@ class NxiqConfiguration } @SuppressWarnings('unused') + @POST FormValidation doVerifyCredentials( @QueryParameter String serverUrl, @QueryParameter String credentialsId) throws IOException { + Jenkins.get().checkPermission(Jenkins.ADMINISTER) return IqUtil.verifyJobCredentials(serverUrl, credentialsId, Jenkins.instance) } }
src/main/java/org/sonatype/nexus/ci/config/Nxrm2Configuration.groovy+5 −0 modified@@ -18,8 +18,10 @@ import org.sonatype.nexus.ci.config.NxrmConfiguration.NxrmDescriptor import hudson.Extension import hudson.util.FormValidation +import jenkins.model.Jenkins import org.kohsuke.stapler.DataBoundConstructor import org.kohsuke.stapler.QueryParameter +import org.kohsuke.stapler.verb.POST import static hudson.util.FormValidation.error import static hudson.util.FormValidation.ok @@ -58,9 +60,12 @@ class Nxrm2Configuration } @Override + @POST FormValidation doVerifyCredentials(@QueryParameter String serverUrl, @QueryParameter String credentialsId) throws IOException { + Jenkins.get().checkPermission(Jenkins.ADMINISTER) + try { def repositories = getApplicableRepositories(serverUrl, credentialsId)
src/main/java/org/sonatype/nexus/ci/config/Nxrm3Configuration.groovy+5 −0 modified@@ -17,8 +17,10 @@ import com.sonatype.nexus.api.exception.RepositoryManagerException import groovy.util.logging.Log import hudson.Extension import hudson.util.FormValidation +import jenkins.model.Jenkins import org.kohsuke.stapler.DataBoundConstructor import org.kohsuke.stapler.QueryParameter +import org.kohsuke.stapler.verb.POST import static hudson.util.FormValidation.error import static hudson.util.FormValidation.ok @@ -80,9 +82,12 @@ class Nxrm3Configuration } @Override + @POST FormValidation doVerifyCredentials(@QueryParameter String serverUrl, @QueryParameter String credentialsId) throws IOException { + Jenkins.get().checkPermission(Jenkins.ADMINISTER) + def repositories def badVersionMsg = ''
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-4g5f-w3mh-w99mghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-50769ghsaADVISORY
- www.jenkins.io/security/advisory/2023-12-13/ghsavendor-advisoryWEB
- www.openwall.com/lists/oss-security/2023/12/13/4ghsaWEB
- github.com/jenkinsci/nexus-platform-plugin/commit/1d5e1e9e457af5e8ce8c9a403933d6cb73542dbdghsaWEB
- github.com/jenkinsci/nexus-platform-plugin/pull/291ghsaWEB
News mentions
1- Jenkins Security Advisory 2023-12-13Jenkins Security Advisories · Dec 13, 2023