VYPR
Moderate severityNVD Advisory· Published Oct 25, 2023· Updated Feb 13, 2025

CVE-2023-46655

CVE-2023-46655

Description

Jenkins CloudBees CD Plugin 1.1.32 and earlier follows symbolic links to locations outside of the directory from which artifacts are published during the 'CloudBees CD - Publish Artifact' post-build step, allowing attackers able to configure jobs to publish arbitrary files from the Jenkins controller file system to the previously configured CloudBees CD server.

AI Insight

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

Jenkins CloudBees CD Plugin 1.1.32 and earlier follows symbolic links during artifact publish, allowing attackers with job configuration access to leak arbitrary files from the Jenkins controller to a CloudBees CD server.

Vulnerability

Analysis

CVE-2023-46655 is a path traversal vulnerability in the Jenkins CloudBees CD Plugin, affecting versions 1.1.32 and earlier. The plugin's 'CloudBees CD - Publish Artifact' post-build step was designed to read files from a job's workspace directory and publish them to a CloudBees CD server. However, the implementation fails to prevent symbolic links within the workspace from pointing outside the intended directory. As a result, when the plugin resolves the path of an artifact to publish, it may follow a symlink to a location elsewhere on the Jenkins controller's file system [1][2].

Exploitation

Prerequisites

An attacker must have at least Job/Configure permission, which allows them to modify a job's configuration. This permission is typically granted to developers or build engineers in many Jenkins environments. The attack does not require any special network position or authentication beyond the Jenkins login. By configuring a job to include a 'CloudBees CD - Publish Artifact' step pointing to a crafted symbolic link, the attacker can cause the plugin to read and transmit arbitrary files from the controller—such as credentials, configuration files stored outside the workspace, or other sensitive data—to the preconfigured CloudBees CD server [2][3].

Impact

Successful exploitation allows an attacker to exfiltrate sensitive files from the Jenkins controller machine to the CloudBees CD server. Since the CloudBees CD server is under the attacker's control (or accessible to them), this leads to unauthorized disclosure of secrets, tokens, or source code residing on the controller. The vulnerability does not grant code execution on the controller, but the information leak can be used to pivot to further attacks on the Jenkins instance or connected systems [2][3].

Mitigation

The vulnerability is patched in CloudBees CD Plugin version 1.1.33, which properly canonicalizes the artifact path and rejects symbolic links pointing outside the workspace. Administrators should upgrade the plugin immediately. No known workarounds are available for unpatched versions. The plugin is not listed as EOL, and this issue is not known to be exploited in the wild as of the advisory date [2][4].

AI Insight generated on May 20, 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:electricflowMaven
< 1.1.331.1.33

Affected products

2

Patches

1
e45ca8428ae4

SECURITY-3237-3238

https://github.com/jenkinsci/electricflow-pluginOleksii VasylkivskyiOct 18, 2023via ghsa
2 files changed · +11 34
  • src/main/java/org/jenkinsci/plugins/electricflow/ElectricFlowClient.java+3 15 modified
    @@ -416,7 +416,8 @@ public String uploadArtifact(
         // http://swarm/reviews/137432/
         String phpUrl = this.electricFlowUrl + "/commander/publishArtifact.php";
         String cgiUrl = this.electricFlowUrl + "/commander/cgi-bin/publishArtifactAPI.cgi";
    -    String requestURL = checkIfEndpointReachable("/commander/publishArtifact.php") ? phpUrl : cgiUrl;
    +    boolean isPhpEndpoint = checkIfEndpointReachable("/commander/publishArtifact.php");
    +    String requestURL = isPhpEndpoint ? phpUrl : cgiUrl;
     
         MultipartUtility multipart =
             new MultipartUtility(requestURL, CHARSET, this.getIgnoreSslConnectionErrors());
    @@ -428,20 +429,7 @@ public String uploadArtifact(
         multipart.addFormField("commanderSessionId", sessionId);
     
         for (File file : fileList) {
    -      if (file.isDirectory()) {
    -
    -        if (!uploadDirectory) {
    -          continue;
    -        }
    -
    -        List<File> dirFiles = FileHelper.getFilesFromDirectory(file);
    -
    -        for (File f : dirFiles) {
    -          multipart.addFilePart("files", f, uploadWorkspace);
    -        }
    -      } else {
    -        multipart.addFilePart("files", file, uploadWorkspace);
    -      }
    +      multipart.addFilePart(isPhpEndpoint ? "files[]" : "files", file, uploadWorkspace);
         }
     
         List<String> response = multipart.finish();
    
  • src/main/java/org/jenkinsci/plugins/electricflow/FileHelper.java+8 19 modified
    @@ -24,6 +24,7 @@
     import java.io.PrintStream;
     import java.io.Writer;
     import java.nio.charset.StandardCharsets;
    +import java.nio.file.Files;
     import java.util.ArrayList;
     import java.util.List;
     import java.util.regex.Pattern;
    @@ -112,24 +113,6 @@ static String[] splitPath(String separator, String path) {
         return list;
       }
     
    -  static List<File> getFilesFromDirectory(final File folder) {
    -    List<File> fileList = new ArrayList<>();
    -    File[] list = folder.listFiles();
    -
    -    if (list == null) {
    -      return fileList;
    -    }
    -
    -    for (final File fileEntry : list) {
    -
    -      if (!fileEntry.isDirectory()) {
    -        fileList.add(fileEntry);
    -      }
    -    }
    -
    -    return fileList;
    -  }
    -
       static List<File> getFilesFromDirectoryWildcardDirScanner(
               String includePattern,
               boolean fullPath,
    @@ -148,7 +131,9 @@ public void visit(File file, String s) throws IOException {
               fileString = s;
             }
             File retFile = new File(fileString);
    -        readFileList.add(retFile);
    +        if (retFile.toPath().toRealPath().startsWith(new File(fullPathValue).toPath().toRealPath())) {
    +          readFileList.add(retFile);
    +        }
           }
         });
         return readFileList;
    @@ -236,6 +221,10 @@ private static boolean __deleteDirectory(File dir) {
         File[] files = dir.listFiles();
         if (files != null) {
           for (final File file : files) {
    +        if (Files.isSymbolicLink(file.toPath())) {
    +          boolean symlinkRemoved = file.delete();
    +          continue;
    +        }
             __deleteDirectory(file);
           }
         }
    

Vulnerability mechanics

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

References

5

News mentions

1