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.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.plugins:p4Maven | < 1.11.5 | 1.11.5 |
Affected products
3- Range: <=1.11.4
- Range: unspecified
Patches
14 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- github.com/advisories/GHSA-h6qv-f5gf-8gcfghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21654ghsaADVISORY
- github.com/jenkinsci/p4-plugin/commit/6b0237b04c985987460e31987d3cb314afa1ead6ghsaWEB
- www.jenkins.io/security/advisory/2021-05-11/ghsax_refsource_CONFIRMWEB
News mentions
1- Jenkins Security Advisory 2021-05-11Jenkins Security Advisories · May 11, 2021