CVE-2023-27898 exposes a stored Cross-Site Scripting (XSS) vulnerability in popular Jenkins versions, impacting both general and Long-Term Support (LTS) releases from 2.270 up to 2.393, and LTS 2.277.1 up to 2.375.3. This issue occurs due to Jenkins not properly escaping plugin dependency version strings when it informs users about plugin incompatibility. As a result, it’s possible for an attacker with control over a plugin update site to inject malicious JavaScript, affecting anyone who interacts with the Jenkins instance where the plugin’s error message appears.

In this article, we'll break down what this CVE means, how it works, and what you can do to stay safe. We’ll provide code snippets, exploitation details, and links to original sources.

What is XSS and Why Does It Matter?

Cross-Site Scripting (XSS) is a type of security vulnerability where attackers can inject malicious scripts into web applications. This is especially dangerous in applications like Jenkins, used widely for automation and CI/CD pipelines, since XSS attacks here can lead to credential theft, session hijacking, and further compromise of DevOps environments.

Where’s the Bug?

When Jenkins reports that a plugin can’t run because its declared dependency requires a newer (or incompatible) version of Jenkins, it shows an error message listing the required version. Jenkins failed to escape this version string, so malicious input would be rendered as HTML – including JavaScript!

Imagine you control a Jenkins update site and craft a plugin whose manifest declares a dependency with the following version:

<jenkins.version><img src=x onerror=alert('xss')></jenkins.version>

When a Jenkins administrator tries to install or upgrade this plugin, Jenkins shows the error

Plugin SomePlugin requires Jenkins <img src=x onerror=alert('xss')> or higher.


But since the version string isn’t escaped, the browser executes the JavaScript inside onerror.

Attacker Position: Control over a Jenkins update site, or ability to publish plugins there.

2. Weaponization: The attacker publishes a malicious plugin, with a cross-site scripting payload in the <jenkins.version> tag.

Trigger Point: An admin tries to install this plugin on a vulnerable Jenkins instance.

4. Impact: The error message about version incompatibility triggers the XSS, running attacker-supplied JavaScript in the admin’s browser.

Simple proof of concept

<jenkins.version><img src=x onerror=alert('Jenkins stored XSS!')></jenkins.version>

Suppose the attacker adds this dependency in their plugin's pom.xml

<properties>
    <jenkins.version"><img src=x onerror=alert('xss')></jenkins.version>
</properties>

Or directly in the plugin manifest file

Jenkins-Version: <img src="x" onerror="alert('xss')">

When Jenkins renders the error

Plugin 'EvilPlugin' requires Jenkins <img src="x" onerror="alert('xss')"> or higher.


If the admin views this in their browser, the script runs instantly.

Remediation and Fix

The fix (see Jenkins Security Advisory) was to ensure the required Jenkins version is properly escaped, so it's safely rendered as text in the browser.

Upgrade Jenkins! The bug is fixed in Jenkins 2.394 and LTS 2.375.4 and above.

- Jenkins properly escapes version strings when showing plugin incompatibility messages from these versions on.

Risk and Mitigation

- Who’s at risk? Jenkins instances that configure untrusted update sites or allow plugins from untrusted sources.
- What can happen? Attackers can execute arbitrary JavaScript in the context of Jenkins users, potentially gaining credentials or performing privileged actions.

Before (Vulnerable)

// Hypothetical code
String requiredVersion = plugin.getRequiredJenkinsVersion();
response.write("Plugin requires Jenkins " + requiredVersion + " or higher");

After (Patched)

import org.apache.commons.text.StringEscapeUtils;

String requiredVersion = plugin.getRequiredJenkinsVersion();
// Properly escape HTML entities before rendering
response.write("Plugin requires Jenkins " + StringEscapeUtils.escapeHtml4(requiredVersion) + " or higher");

References

- Jenkins Security Advisory 2023-03-21 (SECURITY-3048)
- NVD: CVE-2023-27898
- Jenkins Bugtracker Issue

Conclusion

CVE-2023-27898 is a textbook example of how improper input handling can have serious security consequences. Jenkins admins must upgrade as soon as possible, especially if their Jenkins instance can access third-party update sites. Even if you don’t knowingly use untrusted sources, supply chain attacks have shown how quickly plugin repositories can be compromised.

For further reading, see OWASP XSS, and always follow best practices when it comes to plugin management in Jenkins.

Timeline

Published on: 03/10/2023 21:15:00 UTC
Last modified on: 03/16/2023 15:40:00 UTC