CVE-2019-1003025
Description
A missing permission check and CSRF in Jenkins Cloud Foundry Plugin ≤2.3.1 allow attackers with Overall/Read to capture credentials by connecting to an attacker-specified URL.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A missing permission check and CSRF in Jenkins Cloud Foundry Plugin ≤2.3.1 allow attackers with Overall/Read to capture credentials by connecting to an attacker-specified URL.
Vulnerability
The Jenkins Cloud Foundry Plugin version 2.3.1 and earlier does not perform permission checks in the form validation method in AbstractCloudFoundryPushDescriptor.java, allowing users with Overall/Read access to trigger a connection to an arbitrary URL with arbitrary credential IDs [2][3]. Additionally, the method does not require POST requests, leading to a cross-site request forgery (CSRF) vulnerability [2].
Exploitation
An attacker with Overall/Read access to Jenkins can craft a form validation request that connects to an attacker-controlled URL using credential IDs obtained through other means (e.g., by exploiting another vulnerability or reading configuration files) [2]. The lack of CSRF protection also allows an attacker to trick a legitimate administrator into making such a request, escalating the attack vector [2].
Impact
Successful exploitation results in the capture of credentials stored in Jenkins, as the plugin sends them to the attacker-specified URL [2][3]. This leads to credential disclosure, potentially compromising other systems or services.
Mitigation
The vulnerability has been patched in Cloud Foundry Plugin version 2.3.2 [1]. Users should upgrade to this or a later version. If unable to upgrade, the plugin can be disabled or removed until update is applied [2]. No workaround other than upgrading is documented.
AI Insight generated on May 22, 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.jenkins-ci.plugins:cloudfoundryMaven | < 2.3.2 | 2.3.2 |
Affected products
2- Range: 2.3.1 and earlier
Patches
161208697f60bfix SECURITY-876
6 files changed · +175 −67
.gitignore+1 −0 modified@@ -3,3 +3,4 @@ work *.iml .idea src/test/lib +.work
pom.xml+2 −1 modified@@ -80,8 +80,9 @@ They can be overridden via system properties in MAVEN_OPTS, e.g. MAVEN_OPTS="-Dcloudfoundry.target=..." + api.local.pcfdev.io --> - <cloudfoundry.target>api.local.pcfdev.io</cloudfoundry.target> + <cloudfoundry.target></cloudfoundry.target> <cloudfoundry.username>user</cloudfoundry.username> <cloudfoundry.password>pass</cloudfoundry.password> <cloudfoundry.org>pcfdev-org</cloudfoundry.org>
src/main/java/com/hpe/cloudfoundryjenkins/AbstractCloudFoundryPushDescriptor.java+16 −1 modified@@ -9,6 +9,7 @@ import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; import hudson.model.AbstractProject; import hudson.model.Describable; +import hudson.model.Item; import hudson.model.ItemGroup; import hudson.model.Queue; import hudson.model.queue.Tasks; @@ -19,6 +20,8 @@ import hudson.util.ListBoxModel; import java.net.MalformedURLException; import java.net.URL; + +import jenkins.model.Jenkins; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.QueryParameter; @@ -101,7 +104,19 @@ public ListBoxModel doFillCredentialsIdItems(@AncestorInPath ItemGroup context, * @return the validation result */ @SuppressWarnings(value = "unused") - public FormValidation doTestConnection(@AncestorInPath ItemGroup context, @QueryParameter(value = "target") final String target, @QueryParameter(value = "credentialsId") final String credentialsId, @QueryParameter(value = "organization") final String organization, @QueryParameter(value = "cloudSpace") final String cloudSpace, @QueryParameter(value = "selfSigned") final String selfSigned) { + public FormValidation doTestConnection(@AncestorInPath ItemGroup context, + @AncestorInPath Item item, + @QueryParameter(value = "target") final String target, + @QueryParameter(value = "credentialsId") final String credentialsId, + @QueryParameter(value = "organization") final String organization, + @QueryParameter(value = "cloudSpace") final String cloudSpace, + @QueryParameter(value = "selfSigned") final String selfSigned) { + + if (item == null) { + Jenkins.getInstance().checkPermission( Jenkins.ADMINISTER); + } else { + item.checkPermission(Item.CONFIGURE); + } return CloudFoundryUtils.doTestConnection(context, target, credentialsId, organization, cloudSpace, selfSigned); }
src/test/java/com/hpe/cloudfoundryjenkins/CloudFoundryPushBuilderTest.java+70 −32 modified@@ -3,47 +3,30 @@ */ package com.hpe.cloudfoundryjenkins; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.EnvironmentVariable; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ManifestChoice; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ServiceName; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.Service; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.CredentialsScope; import com.cloudbees.plugins.credentials.CredentialsStore; import com.cloudbees.plugins.credentials.domains.Domain; import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.EnvironmentVariable; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ManifestChoice; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.Service; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ServiceName; import hudson.ProxyConfiguration; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.Result; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; -import org.cloudfoundry.client.CloudFoundryClient; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.jvnet.hudson.test.ExtractResourceSCM; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.recipes.WithTimeout; - -import java.io.IOException; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.DeleteApplicationRequest; import org.cloudfoundry.client.v2.routes.DeleteRouteRequest; import org.cloudfoundry.client.v2.servicebindings.DeleteServiceBindingRequest; @@ -65,14 +48,29 @@ import org.cloudfoundry.reactor.uaa.ReactorUaaClient; import org.cloudfoundry.uaa.UaaClient; import org.junit.AfterClass; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeNotNull; +import org.junit.Before; +import org.junit.BeforeClass; import org.junit.ClassRule; +import org.junit.Test; +import org.jvnet.hudson.test.ExtractResourceSCM; import org.jvnet.hudson.test.Issue; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.recipes.WithTimeout; import reactor.core.publisher.Flux; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + public class CloudFoundryPushBuilderTest { private static final String TEST_TARGET = System.getProperty("target"); @@ -114,7 +112,7 @@ private static Optional<org.cloudfoundry.reactor.ProxyConfiguration> buildProxyC } @BeforeClass - public static void initialiseClient() throws IOException { + public static void initialiseClient() throws Exception { // Skip all tests of this class if no test CF platform is specified assumeNotNull(TEST_TARGET); @@ -161,10 +159,7 @@ public static void initialiseClient() throws IOException { .organization(TEST_ORG) .space(TEST_SPACE) .build(); - } - @BeforeClass - public static void setupHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SSLContextBuilder builder = new SSLContextBuilder(); builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( @@ -175,6 +170,9 @@ public static void setupHttpClient() throws NoSuchAlgorithmException, KeyStoreEx @AfterClass public static void cleanCloudSpace() throws IOException { + if(StringUtils.isEmpty( TEST_TARGET )){ + return; + } cloudFoundryOperations.routes() .list(ListRoutesRequest.builder().level(Level.SPACE).build()) .map(route -> DeleteRouteRequest.builder().routeId(route.getId()).build()) @@ -213,15 +211,23 @@ private static List<String> getAppURIs(String appName) { @Before public void setupCredentialsAndCleanCloudSpace() throws IOException { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); cleanCloudSpace(); CredentialsStore store = CredentialsProvider.lookupStores(j.getInstance()).iterator().next(); store.addCredentials(Domain.global(), new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "testCredentialsId", "", TEST_USERNAME, TEST_PASSWORD)); } + private static void assumeNotNull(String value){ + assumeTrue(StringUtils.isNotEmpty( value )); + } + @Test public void testPerformSimplePushManifestFile() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); @@ -250,6 +256,8 @@ public void testPerformSimplePushManifestFile() throws Exception { @Test public void testPerformSimplePushJenkinsConfig() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); ManifestChoice manifest @@ -283,6 +291,8 @@ public void testPerformSimplePushJenkinsConfig() throws Exception { @Test @WithTimeout(600) public void testPerformResetIfExists() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); ManifestChoice manifest1 @@ -327,6 +337,8 @@ public void testPerformResetIfExists() throws Exception { @Test public void testPerformMultipleInstances() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); ManifestChoice manifest @@ -360,6 +372,8 @@ public void testPerformMultipleInstances() throws Exception { @Test public void testPerformCustomBuildpack() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("heroku-node-js-sample.zip"))); ManifestChoice manifest @@ -392,6 +406,8 @@ public void testPerformCustomBuildpack() throws Exception { @Test public void testPerformMultiAppManifest() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-multi-hello-java.zip"))); CloudFoundryPushBuilder cf = new CloudFoundryPushBuilder(TEST_TARGET, TEST_ORG, TEST_SPACE, @@ -430,6 +446,8 @@ public void testPerformMultiAppManifest() throws Exception { @Test public void testPerformCustomManifestFileLocation() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java-custom-manifest-location.zip"))); @@ -463,6 +481,8 @@ public void testPerformCustomManifestFileLocation() throws Exception { @Test @WithTimeout(600) public void testPerformCustomTimeout() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); @@ -489,6 +509,8 @@ public void testPerformCustomTimeout() throws Exception { @Test //TODO fix race condition. public void testPerformEnvVarsManifestFile() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("python-env.zip"))); CloudFoundryPushBuilder cf = new CloudFoundryPushBuilder(TEST_TARGET, TEST_ORG, TEST_SPACE, @@ -518,6 +540,8 @@ public void testPerformEnvVarsManifestFile() throws Exception { @Test public void testPerformServicesNamesManifestFile() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); cloudFoundryOperations.services().createInstance(CreateServiceInstanceRequest.builder() .serviceInstanceName("mysql_service1") .serviceName(TEST_MYSQL_SERVICE_TYPE) @@ -558,6 +582,8 @@ public void testPerformServicesNamesManifestFile() throws Exception { @Test public void testPerformCreateService() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-spring-mysql.zip"))); @@ -592,6 +618,8 @@ public void testPerformCreateService() throws Exception { @Test public void testPerformResetService() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); cloudFoundryOperations.services().createInstance(CreateServiceInstanceRequest.builder() .serviceInstanceName("mysql-spring") // Not the right type of service, must be reset for hello-mysql-spring to work @@ -633,6 +661,8 @@ public void testPerformResetService() throws Exception { @Test public void testPerformNoRoute() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); ManifestChoice manifest @@ -658,6 +688,8 @@ public void testPerformNoRoute() throws Exception { @Test public void testPerformUnknownHost() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); CloudFoundryPushBuilder cf = new CloudFoundryPushBuilder("https://does-not-exist.local", @@ -676,6 +708,8 @@ public void testPerformUnknownHost() throws Exception { @Test public void testPerformWrongCredentials() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-java.zip"))); @@ -700,6 +734,8 @@ public void testPerformWrongCredentials() throws Exception { @Test @Issue("JENKINS-47271") public void testManifestInheritance() throws Exception { + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); FreeStyleProject project = j.createFreeStyleProject(); project.setScm(new ExtractResourceSCM(getClass().getResource("cloudfoundry-hello-spring-mysql-inherited.zip"))); @@ -731,4 +767,6 @@ public void testManifestInheritance() throws Exception { assertTrue("App did not send back correct text", content.contains("State [id=1, stateCode=MA, name=Massachusetts]")); } + + }
src/test/java/com/hpe/cloudfoundryjenkins/CloudFoundryPushPublisherTest.java+37 −33 modified@@ -5,47 +5,30 @@ package com.hpe.cloudfoundryjenkins; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.EnvironmentVariable; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ManifestChoice; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ServiceName; -import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.Service; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.CredentialsScope; import com.cloudbees.plugins.credentials.CredentialsStore; import com.cloudbees.plugins.credentials.domains.Domain; import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.EnvironmentVariable; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ManifestChoice; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.Service; +import com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher.ServiceName; import hudson.ProxyConfiguration; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.Result; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; -import org.cloudfoundry.client.CloudFoundryClient; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.jvnet.hudson.test.ExtractResourceSCM; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.recipes.WithTimeout; - -import java.io.IOException; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.DeleteApplicationRequest; import org.cloudfoundry.client.v2.routes.DeleteRouteRequest; import org.cloudfoundry.client.v2.servicebindings.DeleteServiceBindingRequest; @@ -67,12 +50,27 @@ import org.cloudfoundry.reactor.uaa.ReactorUaaClient; import org.cloudfoundry.uaa.UaaClient; import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.jvnet.hudson.test.ExtractResourceSCM; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.recipes.WithTimeout; +import reactor.core.publisher.Flux; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeNotNull; -import org.junit.ClassRule; -import reactor.core.publisher.Flux; +import static org.junit.Assume.assumeTrue; public class CloudFoundryPushPublisherTest { @@ -114,9 +112,13 @@ private static Optional<org.cloudfoundry.reactor.ProxyConfiguration> buildProxyC .build()); } + private static void assumeNotNull(String value){ + assumeTrue( StringUtils.isNotEmpty( value )); + } + @BeforeClass - public static void initialiseClient() throws IOException { + public static void initialiseClient() throws Exception { // Skip all tests of this class if no test CF platform is specified assumeNotNull(TEST_TARGET); @@ -163,10 +165,7 @@ public static void initialiseClient() throws IOException { .organization(TEST_ORG) .space(TEST_SPACE) .build(); - } - @BeforeClass - public static void setupHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SSLContextBuilder builder = new SSLContextBuilder(); builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( @@ -177,6 +176,9 @@ public static void setupHttpClient() throws NoSuchAlgorithmException, KeyStoreEx @AfterClass public static void cleanCloudSpace() throws IOException { + if(StringUtils.isEmpty( TEST_TARGET )){ + return; + } cloudFoundryOperations.routes() .list(ListRoutesRequest.builder().level(Level.SPACE).build()) .map(route -> DeleteRouteRequest.builder().routeId(route.getId()).build()) @@ -215,8 +217,10 @@ private static List<String> getAppURIs(String appName) { @Before public void setupCredentialsAndCleanCloudSpace() throws IOException { - cleanCloudSpace(); - CredentialsStore store = CredentialsProvider.lookupStores(j.getInstance()).iterator().next(); + // Skip all tests of this class if no test CF platform is specified + assumeNotNull(TEST_TARGET); + cleanCloudSpace(); + CredentialsStore store = CredentialsProvider.lookupStores(j.getInstance()).iterator().next(); store.addCredentials(Domain.global(), new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "testCredentialsId", "", TEST_USERNAME, TEST_PASSWORD));
src/test/java/com/hpe/cloudfoundryjenkins/Security876Test.java+49 −0 added@@ -0,0 +1,49 @@ +package com.hpe.cloudfoundryjenkins; + +import com.gargoylesoftware.htmlunit.HttpMethod; +import com.gargoylesoftware.htmlunit.Page; +import com.gargoylesoftware.htmlunit.WebRequest; +import hudson.model.FreeStyleProject; +import hudson.model.Item; +import jenkins.model.Jenkins; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.MockAuthorizationStrategy; + +import java.net.URL; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +public class Security876Test +{ + @ClassRule + public static JenkinsRule j = new JenkinsRule(); + + @Test + @Ignore("some dependencies issues with spring version the one used by core is too old") + public void rejected_as_no_access() throws Exception { + + j.jenkins.setCrumbIssuer(null); + + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); + FreeStyleProject project = j.createFreeStyleProject(); + + { // as an user with just read access, I may not be able to leak any credentials + JenkinsRule.WebClient wc = j.createWebClient(); + wc.getOptions().setThrowExceptionOnFailingStatusCode( false ); + + String testConnectionUrl = j.getURL() + "descriptorByName/" + CloudFoundryPushPublisher.class.getName() + "/testConnection"; + WebRequest request = new WebRequest( new URL( testConnectionUrl ), HttpMethod.POST ); + + Page page = wc.getPage( request ); + // to avoid trouble, we always validate when the user has not the good permission + assertThat( page.getWebResponse().getStatusCode(), equalTo( 403 ) ); + + } + + } +}
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-2mh9-wpgv-7xr8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2019-1003025ghsaADVISORY
- www.securityfocus.com/bid/107295mitrevdb-entryx_refsource_BID
- github.com/jenkinsci/cloudfoundry-plugin/commit/61208697f60b91ad7f03a4dcec391b6d2115abcaghsaWEB
- jenkins.io/security/advisory/2019-02-19/ghsax_refsource_CONFIRMWEB
- web.archive.org/web/20200227084947/http://www.securityfocus.com/bid/107295ghsaWEB
News mentions
0No linked articles in our index yet.