Safeguard
DevSecOps

Jenkins Remote Code Execution via Groovy Metaclass (CVE-2...

CVE-2016-0792 let attackers bypass Jenkins' deserialization blacklist using Groovy's metaclass to achieve unauthenticated remote code execution via the CLI.

Aman Khan
AppSec Engineer
9 min read

In April 2016, the Jenkins security team disclosed CVE-2016-0792, a remote code execution vulnerability in the Jenkins automation server that let unauthenticated attackers run arbitrary code on the underlying host by sending a specially crafted serialized object to the Jenkins CLI remoting endpoint. The flaw was notable not because it was the first Jenkins deserialization bug — it wasn't — but because it defeated the blacklist-based fix Jenkins had shipped a few months earlier for a nearly identical issue. CVE-2016-0792 abused Groovy's dynamic metaclass machinery to build a new exploitation gadget chain that sailed past the existing class blocklist, turning what should have been a closed hole back into a live remote code execution path.

For any organization running Jenkins as the backbone of its build and release pipeline, this is about as serious as a CI/CD vulnerability gets: full, unauthenticated code execution on the server that holds your source code checkouts, deployment credentials, and signing keys.

CVE-2016-0792: How the Groovy Metaclass Bypass Worked

Jenkins exposes a CLI (command-line interface) that communicates with the master over a remoting protocol. Historically, this protocol accepted serialized Java objects and deserialized them using Java's native serialization along with XStream, a library commonly used to convert XML to and from Java objects. Unrestricted deserialization of attacker-supplied data is dangerous because an attacker doesn't need to find a bug in Jenkins itself — they only need a "gadget chain": a sequence of classes already present on the classpath whose constructors, getters, or readObject/toString methods can be chained together to achieve code execution when instantiated with attacker-controlled data.

This class of bug first hit Jenkins publicly in late 2015, when researchers showed that the Apache Commons Collections library — bundled with Jenkins — contained exactly such a gadget chain, letting attackers pop a shell on any exposed Jenkins CLI port with a single crafted payload. Jenkins responded the way most projects respond to their first deserialization gadget chain: it introduced a blacklist that blocked known-dangerous classes (including Commons Collections) from being instantiated during CLI deserialization.

CVE-2016-0792 is what happened next. Rather than relying on Commons Collections, researchers found that Jenkins' own dependency on Groovy provided everything needed to build a fresh gadget chain. Groovy's metaclass and Expando-style dynamic method dispatch allow arbitrary method invocation through property access and coercion, which meant an attacker could construct a serialized object graph that, once deserialized, used Groovy's own runtime to invoke Runtime.exec() or equivalent — all without touching a single class on the blacklist. In other words, the blacklist approach was a game of whack-a-mole, and Groovy handed attackers another mole. Because the payload traveled to the CLI remoting endpoint before any authentication was checked, exploitation required no valid Jenkins credentials at all.

Affected Versions and Components

CVE-2016-0792 affected the Jenkins core CLI remoting subsystem across both release lines that existed at the time:

  • Jenkins weekly releases prior to the fixed 1.650 release
  • Jenkins LTS (Long-Term Support) releases prior to the fixed 1.642.2 release

The vulnerable component was Jenkins core's handling of serialized objects sent over the CLI remoting channel, combined with the bundled Groovy runtime that supplied the exploitable metaclass gadget. Any Jenkins master with the CLI port reachable by an attacker — which, on many installations, meant the same HTTP(S) port used for the web UI — was exposed regardless of whether the CLI was actively used by administrators. Plugins were not the vector; this was a Jenkins core issue tied to how the master deserialized data before validating it.

CVSS, EPSS, and KEV Context

NVD's published scoring for CVE-2016-0792 reflects a network-exploitable, low-complexity, unauthenticated vulnerability, consistent with the CVSSv2 scoring conventions used for Java deserialization flaws disclosed in that period (base score in the 7.5 range under the AV:N/AC:L/Au:N vector). Deserialization bugs from this era were frequently scored this way because the impact on confidentiality, integrity, and availability was assessed as partial rather than complete, even though real-world exploitation typically achieved full code execution.

CVE-2016-0792 is not currently listed in CISA's Known Exploited Vulnerabilities (KEV) catalog. That's worth reading correctly, though: KEV tracks vulnerabilities with confirmed evidence of active exploitation at the time entries are curated, and it leans heavily toward vulnerabilities still relevant to current attack activity. Jenkins CLI deserialization bugs from 2015–2016, including the closely related CVE-2015-8103, were exploited opportunistically in the wild during and after their disclosure window — internet-wide scanning for exposed Jenkins CLI ports was common — even though they predate KEV's 2021 launch and were never backfilled. Treat the absence from KEV as a reflection of when the catalog exists, not as a signal that exploitation never happened.

We don't have a verified, high-confidence EPSS figure to cite for this specific CVE and won't guess at one. What matters operationally is simpler: this is a pre-authentication, network-reachable RCE in a system that, by design, holds the keys to your software supply chain. That combination has historically correlated with high real-world exploitation regardless of what any single score says.

Timeline

  • Late 2015 — Public research demonstrates that Apache Commons Collections, bundled with Jenkins, provides a Java deserialization gadget chain exploitable through the Jenkins CLI remoting protocol, tracked as CVE-2015-8103. Jenkins ships a fix that blacklists known-dangerous classes from CLI deserialization.
  • Early 2016 — Researchers discover that Jenkins' bundled Groovy runtime enables a second, distinct gadget chain via Groovy's metaclass dispatch, sidestepping the newly introduced blacklist entirely.
  • April 6, 2016 — Jenkins publishes a security advisory disclosing CVE-2016-0792 alongside several other issues, and ships fixed releases: Jenkins 1.650 (weekly) and Jenkins 1.642.2 (LTS). The fix hardens deserialization on the CLI remoting channel rather than simply extending the blacklist further.
  • Following releases — Recognizing that blacklisting was structurally unable to keep pace with new gadget chains, the Jenkins project continued reworking the CLI remoting protocol in subsequent versions, eventually moving toward safer, allowlist-based serialization handling and reducing reliance on raw Java object deserialization for CLI communication.

Remediation Steps

If you are still operating infrastructure old enough to be exposed to CVE-2016-0792 — or auditing legacy systems, appliances, or vendor images that embed an ancient Jenkins instance — the remediation path is well established:

  1. Upgrade Jenkins to 1.650 or later (weekly line) or 1.642.2 or later (LTS line), and from there continue upgrading to a current, actively maintained LTS release. Jenkins has shipped many deserialization and remoting hardening improvements since 2016; staying on a decade-old patch level reintroduces risk even if this specific CVE is closed.
  2. Restrict network exposure of the CLI remoting port. Never expose Jenkins CLI or web interfaces directly to the internet. Place Jenkins behind a VPN, bastion, or an authenticated reverse proxy, and use network policies to limit access to known administrative sources.
  3. Disable the legacy CLI remoting protocol if it isn't actively required. Modern Jenkins supports CLI usage over HTTP with proper authentication instead of the older raw remoting channel that made this class of deserialization attack possible in the first place.
  4. Enforce authentication and authorization on every Jenkins endpoint, including the CLI. Confirm that "allow anonymous read access" and similar permissive defaults are turned off.
  5. Audit plugins and the Groovy script console for exposure. Because Jenkins builds heavily on Groovy for pipeline scripting, any code-execution path — whether through deserialization, the Script Console, or unsanitized pipeline input — deserves the same scrutiny as core CLI vulnerabilities.
  6. Rotate credentials stored in or accessible from Jenkins (SCM tokens, cloud keys, signing certificates) if there is any chance a legacy, unpatched instance was internet-reachable during its lifetime.
  7. Monitor and log CLI and remoting activity, and alert on unexpected process spawning from the Jenkins service account — a strong indicator of deserialization-based exploitation regardless of which specific gadget chain is used.

How Safeguard Helps

CVE-2016-0792 is a decade-old CVE, but the pattern it represents — a build server trusting serialized input, a scripting runtime supplying an unintended code-execution gadget, and a CI/CD system sitting at the center of the software supply chain — is exactly what modern attackers still target. Safeguard is built to catch that pattern before it becomes an incident:

  • Continuous CI/CD asset inventory so you always know which Jenkins masters, agents, and versions exist across your environment — including forgotten instances that never got the 1.642.2/1.650-era patches, let alone anything more recent.
  • Vulnerability and exposure correlation that flags internet-reachable Jenkins CLI and management ports, so a network-exploitable, pre-authentication remote code execution issue like this one gets surfaced as a priority rather than buried in a generic scan report.
  • Supply chain risk scoring that accounts for what a compromised build server actually touches — source repositories, secrets, artifact registries, and deployment pipelines — so teams can prioritize patching Jenkins and similar CI/CD tooling based on blast radius, not just CVSS number.
  • Pipeline and Groovy script visibility for organizations that lean on Jenkinsfile and Groovy-based pipeline logic, helping identify risky script execution patterns and configuration drift that could reopen code-execution paths even after core is patched.
  • Historical CVE and KEV-adjacent tracking so that even vulnerabilities predating CISA's KEV catalog, like CVE-2016-0792, remain part of your organization's ongoing risk picture rather than falling out of view simply because they're old.

Jenkins remains one of the most widely deployed CI/CD platforms in the world, and legacy deployments running years-old versions are more common than most security teams expect. Safeguard's platform is designed to find that exposure, contextualize the risk it carries for your software supply chain, and give teams the prioritized, actionable path to closing it — whether the vulnerability was disclosed last week or, as with CVE-2016-0792, nearly a decade ago.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.