CVE-2025-27624
Description
A cross-site request forgery (CSRF) vulnerability in Jenkins 2.499 and earlier, LTS 2.492.1 and earlier allows attackers to have users toggle their collapsed/expanded status of sidepanel widgets (e.g., Build Queue and Build Executor Status widgets).
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A CSRF vulnerability in Jenkins 2.499 and earlier, LTS 2.492.1 and earlier allows an attacker to toggle sidepanel widget states and inject attacker-controlled content into a user's profile.
Vulnerability
Overview
A cross-site request forgery (CSRF) vulnerability exists in Jenkins versions 2.499 and earlier, as well as LTS 2.492.1 and earlier. The HTTP endpoint responsible for toggling the collapsed/expanded status of sidepanel widgets (such as the Build Queue and Build Executor Status widgets) did not require a POST request. This allowed an attacker to craft a malicious link or page that, when visited by an authenticated Jenkins user, could trigger a state change on the user's sidepanel without their consent [1][3].
Exploitation
Conditions
To exploit this vulnerability, an attacker must trick a logged-in Jenkins user into clicking a crafted link or visiting a malicious webpage. No special network access or authentication is required beyond the victim's existing session. The vulnerable endpoint accepts any arbitrary string as the panel ID, meaning an attacker can supply a crafted paneId parameter. This allows the attacker-controlled value to be stored in the victim's Jenkins user profile, potentially persisting beyond the immediate action [2][3].
Impact
Successful exploitation enables an attacker to manipulate the UI state by collapsing or expanding sidepanel widgets. More significantly, because the endpoint accepts arbitrary panel identifiers, the attacker can inject arbitrary strings into the victim's user profile. This stored content could be used in further attacks, such as injecting script content that might be rendered in other parts of the Jenkins interface (if not properly sanitized). The advisory rates this vulnerability as Medium severity due to the UI manipulation and stored profile injection [1][3].
Mitigation
Jenkins 2.500 and LTS 2.492.2 fix this vulnerability by requiring POST requests for the affected endpoint. The fix also updates the UI links to use a POST-compatible class (collapse post) to ensure CSRF protection is enforced [2][3]. Users are strongly advised to upgrade to these patched versions. No workarounds are mentioned in the advisory for unpatched instances.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jenkins-ci.main:jenkins-coreMaven | >= 2.493, < 2.500 | 2.500 |
org.jenkins-ci.main:jenkins-coreMaven | < 2.492.2 | 2.492.2 |
Affected products
5- Range: <=2.499
- osv-coords3 versions
< 2.492.3-r4+ 2 more
- (no CPE)range: < 2.492.3-r4
- (no CPE)range: >= 2.493.0, < 2.504.1
- (no CPE)range: >= 2.493, < 2.500
- Jenkins Project/Jenkinsv5Range: 2.492.2
Patches
17 files changed · +22 −6
core/src/main/java/jenkins/model/Jenkins.java+1 −0 modified@@ -4165,6 +4165,7 @@ public synchronized HttpRedirect doCancelQuietDown() { return new HttpRedirect("."); } + @POST public HttpResponse doToggleCollapse() throws ServletException, IOException { final StaplerRequest2 request = Stapler.getCurrentRequest2(); final String paneId = request.getParameter("paneId");
core/src/main/resources/lib/hudson/executors.jelly+3 −1 modified@@ -174,7 +174,9 @@ THE SOFTWARE. ${executorDetails} </span> </j:if> - <a class="collapse" href="${rootURL}/toggleCollapse?paneId=executors" + <st:adjunct includes="lib.form.link.link"/> + <!-- TODO improve l:link so the `a` can be changed to `l:link`. --> + <a class="collapse post" href="${rootURL}/toggleCollapse?paneId=executors" tooltip="${paneIsCollapsed ? '%Expand' : '%Collapse'}" data-tooltip-append-to-parent="true"> <j:set var="svgIconId" value="${paneIsCollapsed ? 'chevron-up' : 'chevron-down'}" /> <l:icon src="symbol-${svgIconId}" />
core/src/main/resources/lib/layout/pane.jelly+3 −1 modified@@ -59,7 +59,9 @@ THE SOFTWARE. </span> <j:if test="${attrs.id != null}"> - <a class="collapse" href="${rootURL}/toggleCollapse?paneId=${attrs.id}" + <st:adjunct includes="lib.form.link.link"/> + <!-- TODO improve l:link so the `a` can be changed to `l:link`. --> + <a class="collapse post" href="${rootURL}/toggleCollapse?paneId=${attrs.id}" title="${paneIsCollapsed ? '%expand' : '%collapse'}"> <j:set var="svgIconId" value="${paneIsCollapsed ? 'chevron-up' : 'chevron-down'}" />
test/src/test/java/hudson/model/ComputerSetTest.java+1 −1 modified@@ -173,7 +173,7 @@ public void testTerminatedNodeAjaxExecutorsDoesNotShowTrace() throws Exception { new OfflineCause.ChannelTermination(new RuntimeException(message)) ); - WebClient wc = j.createWebClient(); + WebClient wc = j.createWebClient().withJavaScriptEnabled(false); Page page = wc.getPage(wc.createCrumbedUrl(HasWidgetHelper.getWidget(j.jenkins.getComputer(), ExecutorsWidget.class).orElseThrow().getUrl() + "ajax")); String content = page.getWebResponse().getContentAsString(); assertThat(content, not(containsString(message)));
test/src/test/java/hudson/model/ComputerTest.java+1 −1 modified@@ -285,7 +285,7 @@ public void testTerminatedNodeAjaxExecutorsDoesNotShowTrace() throws Exception { new OfflineCause.ChannelTermination(new RuntimeException(message)) ); - WebClient wc = j.createWebClient(); + WebClient wc = j.createWebClient().withJavaScriptEnabled(false); Page page = wc.getPage(wc.createCrumbedUrl(HasWidgetHelper.getWidget(agent.toComputer(), ExecutorsWidget.class).orElseThrow().getUrl() + "ajax")); String content = page.getWebResponse().getContentAsString(); assertThat(content, not(containsString(message)));
test/src/test/java/jenkins/model/JenkinsTest.java+11 −0 modified@@ -72,6 +72,7 @@ import hudson.util.FormValidation; import hudson.util.HttpResponses; import hudson.util.VersionNumber; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; @@ -130,6 +131,16 @@ public class JenkinsTest { @Rule public TemporaryFolder tmp = new TemporaryFolder(); + @Test + @Issue("SECURITY-3498") + public void testPaneToggleCollapse() throws Exception { + try (WebClient wc = j.createWebClient()) { + final FailingHttpStatusCodeException ex = assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("toggleCollapse?paneId=foo")); + // @POST responds 404 when the verb is wrong; @RequirePOST would respond 405. + assertThat(ex.getStatusCode(), is(HttpServletResponse.SC_NOT_FOUND)); + } + } + @Test @Issue("SECURITY-3073") public void verifyUploadedFingerprintFilePermission() throws Exception {
test/src/test/java/lib/layout/AjaxTest.java+2 −2 modified@@ -61,7 +61,7 @@ public class AjaxTest { @Test @Issue("JENKINS-65288") public void ajaxPageRenderingPossibleWithoutJellyTrace() throws Exception { - JenkinsRule.WebClient wc = r.createWebClient(); + JenkinsRule.WebClient wc = r.createWebClient().withJavaScriptEnabled(false); HtmlPage htmlPage = wc.goTo(getExecutorsWidgetAjaxViewUrl()); r.assertGoodStatus(htmlPage); } @@ -76,7 +76,7 @@ public void ajaxPageRenderingPossibleWithJellyTrace() throws Exception { try { JellyFacet.TRACE = true; - JenkinsRule.WebClient wc = r.createWebClient(); + JenkinsRule.WebClient wc = r.createWebClient().withJavaScriptEnabled(false); HtmlPage htmlPage = wc.goTo(getExecutorsWidgetAjaxViewUrl()); r.assertGoodStatus(htmlPage); } finally {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-7g95-jmg9-h524ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-27624ghsaADVISORY
- www.jenkins.io/security/advisory/2025-03-05/ghsavendor-advisoryWEB
- github.com/jenkinsci/jenkins/commit/84ef1a4d4db17d0ce66522d0141f6e52e2a4c97cghsaWEB
News mentions
1- Jenkins Security Advisory 2025-03-05Jenkins Security Advisories · Mar 5, 2025