CVE-2021-21655
Description
A cross-site request forgery (CSRF) vulnerability in Jenkins P4 Plugin 1.11.4 and earlier allows attackers 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.
CSRF vulnerability in Jenkins P4 Plugin 1.11.4 and earlier lets attackers connect to an attacker-controlled Perforce server with arbitrary credentials.
Vulnerability
A cross-site request forgery (CSRF) vulnerability exists in the Jenkins P4 Plugin up to version 1.11.4. The plugin's "Test Connection" button or similar functionality does not enforce CSRF protection, allowing an attacker to craft a request that causes a victim Jenkins user to unknowingly initiate a connection to an attacker-specified Perforce server using attacker-controlled username and password. The vulnerability is present in all versions 1.11.4 and earlier [1][2].
Exploitation
An attacker can exploit this vulnerability by tricking a Jenkins user with appropriate permissions (typically Job/Configure or similar) into visiting a malicious web page, clicking a link, or submitting a crafted form. The attacker does not need authentication to Jenkins but relies on the victim's active session. The crafted request triggers the "Test Connection" action, which uses attacker-specified Perforce server host, port, username, and password parameters [1]. The attack is a standard CSRF scenario, requiring no additional privileges on the attacker's part beyond social engineering or cross-site request delivery.
Impact
Successful exploitation allows the attacker to make Jenkins connect to an arbitrary Perforce server controlled by the attacker, using credentials supplied by the attacker. This could lead to information disclosure if the victim's Jenkins environment inadvertently exposes credentials or server details, or could be used as a stepping stone for further attacks against the Jenkins instance or its connected network. The attacker does not gain direct code execution or credential theft, but the ability to control the Perforce connection parameters could be misused for reconnaissance or to exfiltrate build artifacts [1][2].
Mitigation
The vulnerability is fixed in P4 Plugin version 1.11.5, released on 2021-05-11. Jenkins administrators should upgrade to version 1.11.5 or later. No workaround is available other than upgrading. The fix also adds an admin-only check to the "Test Connection" button, as shown in the commit diff [4], requiring administrators to perform the action, reducing the CSRF risk [1].
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-3rj3-qp2j-4fj2ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21655ghsaADVISORY
- 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