The vulnerability is a stored cross-site scripting (XSS) issue in Jenkins. It occurs when an attacker with Agent/Configure permission sends a specially crafted config.xml via a POST request to update an agent's configuration. The root cause is the improper handling of the agent's offline cause description.
The analysis of the patch commit 20041e8090d3b228d586169141ea7f12ffe4444d reveals the following:
-
Entry Point: The added test case postConfigXmlWithNonUserCause in jenkins.security.Security3669Test.java clearly shows that the vulnerability is triggered by calling hudson.model.Computer.updateByXml. This function accepts the XML configuration containing the XSS payload in the <description> tag of a hudson.slaves.OfflineCause$SimpleOfflineCause.
-
Vulnerable Rendering: The patch modifies the Jelly template hudson/slaves/OfflineCause/cause.jelly. The change from <j:out value="${it}" /> to ${it} is critical. The <j:out> tag performs HTML escaping. By removing it, the template now relies on the object it (which is an instance of OfflineCause) to provide a pre-escaped string via its toString() method. Before the patch, OfflineCause.toString() (specifically for SimpleOfflineCause) returned the raw description, which the UI would then render, executing any embedded scripts.
-
The Fix: The patch implies a change in the hudson.slaves.OfflineCause.toString() method to ensure it returns an HTML-escaped string. This is further evidenced by the removal of an overriding toString() method in the OfflineCause.UserCause inner class, suggesting the base class now handles the escaping, making the override redundant.
Therefore, during exploitation, a runtime profile would show calls to hudson.model.Computer.updateByXml when the malicious configuration is submitted, and subsequently, calls to hudson.slaves.OfflineCause.toString when the agent's status page is viewed, which is where the XSS payload would have been rendered.