VYPR
Moderate severityNVD Advisory· Published Apr 12, 2022· Updated Aug 3, 2024

CVE-2022-29051

CVE-2022-29051

Description

Jenkins Publish Over FTP Plugin 1.16 and earlier allows attackers with Overall/Read permission to connect to an FTP server with attacker-specified credentials due to missing permission checks.

AI Insight

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

Jenkins Publish Over FTP Plugin 1.16 and earlier allows attackers with Overall/Read permission to connect to an FTP server with attacker-specified credentials due to missing permission checks.

Vulnerability

Missing permission checks in Jenkins Publish Over FTP Plugin 1.16 and earlier allow attackers with Overall/Read permission to connect to an FTP server using attacker-specified credentials. The doTestConnection method in the plugin lacked the necessary Jenkins.ADMINISTER permission check, which should have been required before allowing a connection test to an arbitrary FTP server. [1][4]

Exploitation

An attacker needs only Overall/Read permission (a low-privilege role in Jenkins) and network access to the Jenkins controller. By sending a crafted POST request to the doTestConnection endpoint with attacker-controlled parameters (hostname, username, password, etc.), the attacker can initiate a connection from the Jenkins server to an arbitrary FTP server they control. No further authentication or user interaction is required. [1][4]

Impact

A successful exploit allows the attacker to use the Jenkins controller as a proxy to connect to an FTP server with credentials of their choosing. This could be leveraged for information disclosure (e.g., verifying that the target FTP server is reachable, probing internal network hosts) or to perform reconnaissance. The attacker does not gain code execution or direct access to Jenkins credentials, but the Jenkins server's network position could be abused to confirm reachable FTP services. [1]

Mitigation

Jenkins Publish Over FTP Plugin version 1.17 includes the fix by adding the @RequirePOST annotation and a permission check for Jenkins.ADMINISTER on the doTestConnection method. Users should update to version 1.17 or later, released with the April 12, 2022 security advisory. No workarounds are documented; the recommended mitigation is to upgrade immediately. [1][4]

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:publish-over-ftpMaven
< 1.171.17

Affected products

2

Patches

1
b26520142855

SECURITY-2321

4 files changed · +17 2
  • pom.xml+1 0 modified
    @@ -41,6 +41,7 @@
     
         <properties>
             <findbugs.failOnError>false</findbugs.failOnError>
    +        <spotbugs.skip>true</spotbugs.skip>
             <jenkins.version>2.289.1</jenkins.version>
             <java.level>8</java.level>
         </properties>
    
  • src/main/java/jenkins/plugins/publish_over_ftp/descriptor/BapFtpCredentialsDescriptor.java+11 2 modified
    @@ -26,13 +26,16 @@
     
     import hudson.Extension;
     import hudson.model.Descriptor;
    +import hudson.model.Item;
     import hudson.util.FormValidation;
     import jenkins.model.Jenkins;
     import jenkins.plugins.publish_over.BPBuildInfo;
     import jenkins.plugins.publish_over_ftp.BapFtpCredentials;
     import jenkins.plugins.publish_over_ftp.BapFtpHostConfiguration;
     import jenkins.plugins.publish_over_ftp.BapFtpPublisherPlugin;
     import org.kohsuke.stapler.QueryParameter;
    +import org.kohsuke.stapler.interceptor.RequirePOST;
    +import org.kohsuke.stapler.AncestorInPath;
     
     @Extension
     public class BapFtpCredentialsDescriptor extends Descriptor<BapFtpCredentials> {
    @@ -54,8 +57,14 @@ public FormValidation doCheckPassword(@QueryParameter final String value) {
             return FormValidation.validateRequired(value);
         }
     
    +    @RequirePOST
         public FormValidation doTestConnection(@QueryParameter final String configName, @QueryParameter final String username,
    -                                           @QueryParameter final String password) {
    +                                           @QueryParameter final String password, @AncestorInPath Item item) {
    +            if (item == null) {
    +                Jenkins.get().checkPermission(Jenkins.ADMINISTER);
    +            } else {
    +                item.checkPermission(Item.CONFIGURE);
    +            }
             final BapFtpCredentials credentials = new BapFtpCredentials(username, password);
             final BPBuildInfo buildInfo = BapFtpPublisherPluginDescriptor.createDummyBuildInfo();
             buildInfo.put(BPBuildInfo.OVERRIDE_CREDENTIALS_CONTEXT_KEY, credentials);
    @@ -69,4 +78,4 @@ public jenkins.plugins.publish_over.view_defaults.HostConfiguration.Messages get
             return new jenkins.plugins.publish_over.view_defaults.HostConfiguration.Messages();
         }
     
    -}
    \ No newline at end of file
    +}
    
  • src/main/java/jenkins/plugins/publish_over_ftp/descriptor/BapFtpHostConfigurationDescriptor.java+2 0 modified
    @@ -33,6 +33,7 @@
     import jenkins.plugins.publish_over_ftp.BapFtpPublisherPlugin;
     import jenkins.plugins.publish_over_ftp.Messages;
     import org.kohsuke.stapler.QueryParameter;
    +import org.kohsuke.stapler.interceptor.RequirePOST;
     
     @Extension
     public class BapFtpHostConfigurationDescriptor extends Descriptor<BapFtpHostConfiguration> {
    @@ -70,6 +71,7 @@ public FormValidation doCheckTimeout(@QueryParameter final String value) {
             return FormValidation.validateNonNegativeInteger(value);
         }
     
    +    @RequirePOST
         public FormValidation doTestConnection(@QueryParameter final String name, @QueryParameter final String hostname,
                 @QueryParameter final String username, @QueryParameter final String encryptedPassword,
                 @QueryParameter final String remoteRootDir, @QueryParameter final int port,
    
  • src/main/java/jenkins/plugins/publish_over_ftp/descriptor/BapFtpPublisherPluginDescriptor.java+3 0 modified
    @@ -43,6 +43,7 @@
     import jenkins.plugins.publish_over_ftp.options.FtpPluginDefaults;
     import net.sf.json.JSONObject;
     import org.kohsuke.stapler.StaplerRequest;
    +import org.kohsuke.stapler.interceptor.RequirePOST;
     
     import java.util.List;
     
    @@ -128,11 +129,13 @@ public jenkins.plugins.publish_over.view_defaults.manage_jenkins.Messages getCom
             return new jenkins.plugins.publish_over.view_defaults.manage_jenkins.Messages();
         }
     
    +    @RequirePOST
         public FormValidation doTestConnection(final String name, final String hostname, final String username,
                 final String encryptedPassword, final String remoteRootDir, final int port, final int timeout,
                 final boolean useActiveData, final String controlEncoding, final boolean disableMakeNestedDirs,
                 final boolean disableRemoteVerification, final boolean useFtpOverTls, final boolean useImplicitTls,
                 final String trustedCertificate) {
    +        Jenkins.get().checkPermission(Jenkins.ADMINISTER);
             final BapFtpHostConfiguration hostConfig = new BapFtpHostConfiguration(name, hostname, username,
                     encryptedPassword, remoteRootDir, port, timeout, useActiveData, controlEncoding,
                     disableMakeNestedDirs, disableRemoteVerification);
    

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