VYPR
Moderate severityNVD Advisory· Published May 11, 2021· Updated Aug 3, 2024

CVE-2021-21654

CVE-2021-21654

Description

Jenkins P4 Plugin 1.11.4 and earlier does not perform permission checks in multiple HTTP endpoints, allowing attackers with Overall/Read permission to connect to an attacker-specified Perforce server using attacker-specified username and password.

AI Insight

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

Jenkins P4 Plugin 1.11.4 and earlier lacks permission checks, allowing attackers with Overall/Read to connect to an attacker-controlled Perforce server with supplied credentials.

Vulnerability

Jenkins P4 Plugin version 1.11.4 and earlier fails to perform required permission checks in multiple HTTP endpoints [1][2]. This allows any user with the Overall/Read permission to reach functionality that should be restricted, such as the "Test Connection" button. The plugin does not verify that the user has the appropriate level of access before allowing them to specify a Perforce server and credentials [1].

Exploitation

An attacker needs only the Overall/Read permission in Jenkins, which is a relatively low privilege [1][2]. The attacker can send crafted HTTP requests to the vulnerable endpoints, specifying an arbitrary Perforce server host/port and a username/password of their choice. The plugin will then attempt to connect to that attacker-specified server using those credentials [2]. No further user interaction or write access is required.

Impact

By exploiting this vulnerability, an attacker can cause the Jenkins controller to connect to a malicious Perforce server under the attacker's control. The attacker can then observe connection attempts, capture credentials used (e.g., in transit or logs), or potentially stage further attacks against the Jenkins environment [1][2]. This constitutes a medium-severity information disclosure and a potential pivot point for broader compromise.

Mitigation

Jenkins P4 Plugin version 1.11.5 fixed this issue by adding an <l:isAdmin> check around the "Test Connection" button [4]. The fix was released as part of the 2021-05-11 Jenkins security advisory [1]. Users should upgrade to P4 Plugin 1.11.5 or later. There is no known workaround short of removing the Overall/Read permission from untrusted users or disabling the plugin [1][2].

AI Insight generated on May 21, 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
org.jenkins-ci.plugins:p4Maven
< 1.11.51.11.5

Affected products

3

Patches

1
6b0237b04c98

SECURITY-2327

https://github.com/jenkinsci/p4-pluginPaul AllenMay 7, 2021via ghsa
4 files changed · +28 8
  • src/main/java/org/jenkinsci/plugins/p4/credentials/P4PasswordImpl.java+8 0 modified
    @@ -6,13 +6,15 @@
     import hudson.Extension;
     import hudson.util.FormValidation;
     import hudson.util.Secret;
    +import jenkins.model.Jenkins;
     import org.jenkinsci.Symbol;
     import org.jenkinsci.plugins.p4.client.ConnectionConfig;
     import org.jenkinsci.plugins.p4.client.ConnectionFactory;
     import org.jenkinsci.plugins.p4.client.ConnectionHelper;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.DataBoundSetter;
     import org.kohsuke.stapler.QueryParameter;
    +import org.kohsuke.stapler.verb.POST;
     
     import javax.servlet.ServletException;
     import java.io.IOException;
    @@ -67,6 +69,7 @@ public FormValidation doCheckP4port(@QueryParameter String value) {
     			return FormValidation.ok();
     		}
     
    +		@POST
     		public FormValidation doTestConnection(@QueryParameter("p4port") String p4port,
     		                                       @QueryParameter("ssl") String ssl,
     		                                       @QueryParameter("trust") String trust,
    @@ -75,6 +78,11 @@ public FormValidation doTestConnection(@QueryParameter("p4port") String p4port,
     		                                       @QueryParameter("password") String password,
     		                                       @QueryParameter("allhosts") boolean allhosts)
     				throws IOException, ServletException {
    +
    +			if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) {
    +				return FormValidation.warning("Insufficient permissions");
    +			}
    +
     			try {
     				// Test connection path to Server
     				TrustImpl sslTrust = ("true".equals(ssl)) ? new TrustImpl(trust) : null;
    
  • src/main/java/org/jenkinsci/plugins/p4/credentials/P4TicketImpl.java+8 0 modified
    @@ -5,12 +5,14 @@
     import edu.umd.cs.findbugs.annotations.NonNull;
     import hudson.Extension;
     import hudson.util.FormValidation;
    +import jenkins.model.Jenkins;
     import org.jenkinsci.Symbol;
     import org.jenkinsci.plugins.p4.client.ConnectionConfig;
     import org.jenkinsci.plugins.p4.client.ConnectionFactory;
     import org.jenkinsci.plugins.p4.client.ConnectionHelper;
     import org.kohsuke.stapler.DataBoundConstructor;
     import org.kohsuke.stapler.QueryParameter;
    +import org.kohsuke.stapler.verb.POST;
     
     import javax.servlet.ServletException;
     import java.io.IOException;
    @@ -68,6 +70,7 @@ public FormValidation doCheckP4port(@QueryParameter String value) {
     			return FormValidation.ok();
     		}
     
    +		@POST
     		public FormValidation doTestConnection(@QueryParameter("p4port") String p4port,
     		                                       @QueryParameter("ssl") String ssl,
     		                                       @QueryParameter("trust") String trust,
    @@ -77,6 +80,11 @@ public FormValidation doTestConnection(@QueryParameter("p4port") String p4port,
     		                                       @QueryParameter("ticketValue") String ticketValue,
     		                                       @QueryParameter("ticketPath") String ticketPath)
     				throws IOException, ServletException {
    +
    +			if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) {
    +				return FormValidation.warning("Insufficient permissions");
    +			}
    +
     			try {
     				// Test connection path to Server
     				TrustImpl sslTrust = ("true".equals(ssl)) ? new TrustImpl(trust) : null;
    
  • src/main/resources/org/jenkinsci/plugins/p4/credentials/P4PasswordImpl/credentials.jelly+6 4 modified
    @@ -1,5 +1,5 @@
     <?jelly escape-by-default='true'?>
    -<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler">
    +<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler" xmlns:l="/lib/layout">
     
     	<st:include page="id-and-description" class="${descriptor.clazz}"/>
     	
    @@ -41,8 +41,10 @@
     			<f:textbox/>
     		</f:entry>
     	</f:advanced>
    -	
    -	<f:validateButton title="${%Test Connection}" progress="${%Testing...}"
    -		method="testConnection" with="p4port,ssl,trust,p4host,username,password,allhosts" />
    +
    +	<l:isAdmin>
    +		<f:validateButton title="${%Test Connection}" progress="${%Testing...}"
    +			method="testConnection" with="p4port,ssl,trust,p4host,username,password,allhosts" />
    +	</l:isAdmin>
       
     </j:jelly>
    \ No newline at end of file
    
  • src/main/resources/org/jenkinsci/plugins/p4/credentials/P4TicketImpl/credentials.jelly+6 4 modified
    @@ -1,5 +1,5 @@
     <?jelly escape-by-default='true'?>
    -<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler">
    +<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler" xmlns:l="/lib/layout">
     
     	<st:include page="id-and-description" class="${descriptor.clazz}"/>
     	
    @@ -45,8 +45,10 @@
     			<f:textbox/>
     		</f:entry>
     	</f:advanced>
    -	
    -	<f:validateButton title="${%Test Connection}" progress="${%Testing...}"
    -		method="testConnection" with="p4port,ssl,trust,username,p4host,ticket,ticketValue,ticketPath" />
    +
    +	<l:isAdmin>
    +		<f:validateButton title="${%Test Connection}" progress="${%Testing...}"
    +			method="testConnection" with="p4port,ssl,trust,username,p4host,ticket,ticketValue,ticketPath" />
    +	</l:isAdmin>
     		
     </j:jelly>
    

Vulnerability mechanics

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

References

4

News mentions

1