Jenkins CVE-2024-23897 is a CVSS 9.8 arbitrary file-read vulnerability in the Jenkins CLI that SonarSource researcher Yaniv Nizry disclosed on January 24, 2024. The root cause is an argument-expansion feature that treats command-line arguments starting with @ as file references and reads their contents into the argument string. Because the CLI is reachable pre-authentication over multiple transports on a default Jenkins install, any attacker who can send a CLI command can read files from the controller file system, including the secrets directory that stores Jenkins credentials. Trend Micro and others reported mass scanning and exploitation attempts within 72 hours of disclosure, and CISA added CVE-2024-23897 to the Known Exploited Vulnerabilities catalog in August 2024.
What is the technical root cause of CVE-2024-23897?
The technical root cause of CVE-2024-23897 is that Jenkins builds its CLI command parser on top of the args4j library with the expandAtFiles feature enabled, and the feature silently replaces any argument beginning with @ with the contents of the referenced file. The feature predates the current Jenkins CLI codebase and was never intended to be reachable by untrusted input, but the CLI endpoint on a default Jenkins install accepts commands from anonymous users for read-only operations such as help and who-am-i. Those commands accept arguments, and an argument like @/etc/passwd causes the CLI parser to read that file and either echo it back in an error message or embed it in the output of the command.
SonarSource's disclosure walks through the specific commands that produce the most readable output: connect-node, enable-job, help, and several others. The error path for an unknown option typically echoes the offending argument back to the client, which leaks the file contents verbatim. This makes the vulnerability essentially a one-shot read of any file the Jenkins process can open.
Which Jenkins versions and deployment modes are affected?
Affected versions are Jenkins weekly builds 2.441 and earlier and Jenkins LTS 2.426.2 and earlier. Patched versions are 2.442 on the weekly track and 2.426.3 on the LTS track. All officially supported deployment modes are affected: the controller on bare metal, controllers inside containers, Jenkins Operator on Kubernetes, and the CloudBees CI distribution. CloudBees issued a coordinated advisory the same day referencing the upstream CVE.
The CLI endpoint is reachable on:
- HTTP over the main Jenkins web port via
/cliwith a custom transport handshake - WebSocket over the same HTTP port when the client opts into WebSocket transport
- TCP over the "JNLP agent" port when it is enabled (default off on modern installs but commonly on in older estates)
- SSH over the Jenkins SSH port when that interface is enabled
Mass-scanning exploitation focused on HTTP because it is the lowest-friction path and is enabled by default. Estates that explicitly hardened the HTTP transport but left the JNLP or SSH listeners exposed were equally vulnerable.
How is the file-read leveraged into RCE?
The file-read is leveraged into RCE by exfiltrating the Jenkins secret key and using it to forge authenticated CLI requests or deserialize stored credentials. Jenkins stores all credentials encrypted with a master key in $JENKINS_HOME/secrets/master.key wrapped by a key in $JENKINS_HOME/secrets/hudson.util.Secret. With both files in hand, an attacker can decrypt every credential in the Jenkins credential store. That routinely includes:
- SSH private keys used by builds to reach source-code repositories
- Cloud credentials (AWS access keys, GCP service accounts, Azure client secrets) used by deployment jobs
- API tokens for artifact registries, container registries, and downstream systems
- Kubernetes kubeconfig files for pipeline deployers
- Domain credentials for integration tests that touch Active Directory
SonarSource and Trend Micro both published post-disclosure analyses describing a second escalation path: reading $JENKINS_HOME/users/*/config.xml to extract API tokens for existing user accounts. Those tokens authenticate to the normal Jenkins API and can trigger jobs that run scripts. A pipeline step that runs a shell script then grants arbitrary code execution on the controller or on a build agent.
The shortest documented exploit path reported publicly is: read master.key and hudson.util.Secret, decrypt an admin user's API token from the users directory, submit a crafted groovy script through the script console, and execute arbitrary code as the Jenkins process. Every step is documented in the Jenkins source tree and has been reimplemented in public PoCs.
What public IoCs should defenders look for?
Public IoCs to look for were published by Trend Micro, SANS ISC, and several IR firms in the weeks after disclosure. Notable indicators as reported:
- HTTP requests to
/clior/cli?remoting=falsefrom unknown source IPs in close succession - Requests whose POST body contains the literal
@/or@C:\patterns - Jenkins access logs showing
connect-node,enable-job,help, or other CLI commands issued without a corresponding authenticated session - Outbound connections from the Jenkins controller to newly seen destinations shortly after a CLI request
- New admin users or new API tokens created without a matching audit entry in the job-history stream
Host-level detection:
- Read access to
$JENKINS_HOME/secrets/master.keyby the Jenkins process outside of startup - Access to
$JENKINS_HOME/users/*/config.xmloutside the user-management UI workflow - The
javaprocess hosting Jenkins spawningsh,bash,cmd.exe, orpowershell.exein ways that do not match normal pipeline steps - Unexpected writes to
$JENKINS_HOME/jobs/*or$JENKINS_HOME/init.groovy.d/
Several public PoCs set User-Agent to Java/<version> verbatim, which is the default for the official CLI client. That is not reliable on its own but was the fingerprint of the earliest mass-scanning wave reported by GreyNoise.
What does the exploitation requirement profile look like?
The exploitation requirement profile is intentionally narrow and that is why the CVE scored 9.8. Exploitation requires network reachability to any of the CLI transports and no authentication for a useful file read. The anonymous overall/read permission that most Jenkins installs disable by default does not actually protect the CLI help path because the arg parsing runs before the permission check. That detail caught many defenders off-guard: their security report showed "anonymous access denied" yet they were still exploitable.
Authenticated exploitation is strictly more powerful. A low-privilege authenticated user gains access to CLI commands that produce longer error outputs, which allows reading files up to multiple megabytes. Unauthenticated exploitation is typically limited to a few kilobytes per request, but multi-request chunking strategies have been demonstrated publicly.
What exploitation does not require:
- The Jenkins controller to be internet-facing (internal-only estates were still compromised via lateral movement after other initial-access vectors)
- Any specific plugin to be installed (the CLI is built into core)
- The attacker to have user enumeration or brute-force capability
What is the patch and hardening plan?
The patch plan is to upgrade to Jenkins 2.442 weekly or 2.426.3 LTS or later, and as a compensating control to disable the CLI where it is not needed. The Jenkins project explicitly recommends disabling the CLI if your automation does not use it, and exposes a startup flag and UI toggle that removes every transport. Most production estates do not use the CLI at all because automation uses the REST API, Jenkinsfile pipelines, or dedicated plugins.
Remediation sequence:
- Upgrade to the fixed version across controllers and the CloudBees distribution
- Rotate every credential in the Jenkins credential store, treating all of them as compromised until proven otherwise
- Rotate the Jenkins
master.keyby regenerating and re-encrypting the credential store (the Jenkins project documents the procedure) - Invalidate and reissue API tokens for every user
- Audit
$JENKINS_HOME/users/for unknown accounts or recently created tokens - Audit pipeline job XML for injected
scriptblocks, new SCM URLs, or modified credentials
Hardening that pays dividends beyond this CVE:
- Disable the CLI entirely unless a documented automation requires it
- Front Jenkins with an authenticating reverse proxy and restrict
/clito admin source networks - Place Jenkins controllers in a management VLAN and require jump-host access
- Pin plugin versions and enable automated plugin security updates
What are the supply chain implications?
The supply chain implications are severe because Jenkins controllers are commonly the single most credential-dense host in an engineering organization. A breach that exfiltrates the credential store effectively hands the attacker the deploy-time identity of the organization, which is stronger than most application-layer compromises because it lets the attacker ship code changes that downstream systems implicitly trust.
Organizations that ship open-source projects are a particular concern. Several high-profile open-source projects use Jenkins controllers to sign releases, and those signing keys are stored in the credential store. An exfiltrated signing key allows an attacker to ship backdoored releases that verify correctly until the key is rotated, which requires coordinating with every downstream consumer. The 2020 SolarWinds incident and the 2023 3CX incident both illustrated how destructive this specific primitive is.
Questions to push to vendors whose products build on Jenkins:
- Is the CLI enabled on managed-service Jenkins tenants
- What is the SLA for propagating Jenkins core security updates
- How is the credential store segmented between tenants or projects
How Safeguard.sh Helps
Safeguard.sh inventories Jenkins controllers and the plugin ecosystem through 100-level dependency depth analysis, surfacing every controller, agent, and CloudBees CI tenant plus the specific plugin versions loaded at runtime. Reachability analysis cuts 60 to 80 percent of findings by confirming which controllers actually expose /cli, the JNLP port, or SSH to reachable networks, so the patch queue reflects real attacker paths rather than installed-count. Griffin AI autonomously proposes controller upgrade orchestration across weekly and LTS fleets, generates CLI-disable configuration deltas, and drafts credential rotation plans scoped to the affected controllers. Container self-healing rebuilds containerized Jenkins deployments against patched base images without manual pipeline intervention, and SBOM generation captures the plugin inventory that most organizations lack, so supply-chain reviews reflect actual deployed code.