CVE-2020-2289
Description
Jenkins Active Choices Plugin 2.4 and earlier has a stored XSS vulnerability via unescaped build parameter names and descriptions, exploitable by attackers with Job/Configure permission.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins Active Choices Plugin 2.4 and earlier has a stored XSS vulnerability via unescaped build parameter names and descriptions, exploitable by attackers with Job/Configure permission.
Vulnerability
Overview
The Jenkins Active Choices Plugin, which provides dynamic scripted parameters for freestyle jobs, fails to escape the name and description of build parameters in versions 2.4 and earlier. This oversight allows attackers to inject arbitrary HTML and JavaScript into these fields, leading to a stored cross-site scripting (XSS) vulnerability [1][2][3]. The plugin's reliance on HTML rendering for parameter UI widgets, as noted in its documentation, increases the risk of such injection [1].
Exploitation
Prerequisites
To exploit this vulnerability, an attacker must have Job/Configure permission on a Jenkins job. With this access, they can craft malicious parameter names or descriptions that are stored in the job configuration. When other users (including administrators) view the job configuration or trigger builds, the injected script executes in their browser context [2][4]. No additional authentication or network position is required beyond the initial permission.
Impact
Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of the victim's Jenkins session. This can lead to credential theft, unauthorized actions (e.g., creating or deleting jobs), and further compromise of the Jenkins instance. The stored XSS persists until the malicious parameter is removed or the plugin is updated [2][3].
Mitigation
The vulnerability is fixed in Active Choices Plugin version 2.5. Users are strongly advised to upgrade immediately. No workarounds are available; the only remediation is to apply the patched version [4].
- GitHub - jenkinsci/active-choices-plugin: This plugin provides new scripted, dynamic parameters for freestyle jobs that can be rendered as combo-boxes, check-boxes, radio-buttons or rich HTML UI widgets.
- Jenkins Security Advisory 2020-10-08
- NVD - CVE-2020-2289
- security - Multiple vulnerabilities in Jenkins plugins
AI Insight generated on May 21, 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.biouno:uno-choiceMaven | < 2.5 | 2.5 |
Affected products
2- Range: 2.1
Patches
159bbd4a963db[SECURITY-1954]
2 files changed · +98 −1
src/main/resources/org/biouno/unochoice/common/choiceParameterCommon.jelly+1 −1 modified@@ -7,7 +7,7 @@ <j:set var="paramName" value="${it.randomName}" scope="parent" /> <j:set var="choiceType" value="${it.choiceType}"/> <j:set var="escapeEntryTitleAndDescription" value="false"/> - <f:entry title="${it.name}" description="${it.description}"> + <f:entry title="${h.escape(it.name)}" description="${it.formattedDescription}"> <div name="parameter" description="${it.formattedDescription}" id='${paramName}'> <input type="hidden" name="name" value="${h.escape(it.name)}" /> <j:choose>
src/test/java/org/biouno/unochoice/jenkins_cert_1954/TestParametersXssVulnerabilities.java+97 −0 added@@ -0,0 +1,97 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2014-2020 Ioannis Moutsatsos, Bruno P. Kinoshita + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.biouno.unochoice.jenkins_cert_1954; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; + +import org.biouno.unochoice.ChoiceParameter; +import org.biouno.unochoice.model.GroovyScript; +import org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.JenkinsRule.WebClient; +import org.xml.sax.SAXException; + +import com.gargoylesoftware.htmlunit.html.DomElement; +import com.gargoylesoftware.htmlunit.html.DomNodeList; +import com.gargoylesoftware.htmlunit.html.HtmlPage; + +import hudson.model.FreeStyleProject; +import hudson.model.ParametersDefinitionProperty; + +/** + * Tests against XSS. See SECURITY-1954, and SECURITY-2008. + * @since 2.5 + */ +public class TestParametersXssVulnerabilities { + + @Rule + public JenkinsRule j = new JenkinsRule(); + + /** + * Tests that a {@code ChoiceParameter} using a Groovy script has its output value sanitized against XSS when + * returning a List. + * @throws IOException + * @throws SAXException + */ + @Test + public void testChoicesParameterXss() throws IOException, SAXException { + String xssString = "<img src=x onerror=alert(123)>"; + FreeStyleProject project = j.createFreeStyleProject(); + String scriptText = String.format("return '%s'", xssString); + SecureGroovyScript secureScript = new SecureGroovyScript(scriptText, true, null); + GroovyScript script = new GroovyScript(secureScript, secureScript); + ChoiceParameter parameter = new ChoiceParameter( + xssString, + xssString, + "random-name", + script, + ChoiceParameter.PARAMETER_TYPE_CHECK_BOX, + false, + 0); + project.addProperty(new ParametersDefinitionProperty(parameter)); + project.save(); + + WebClient wc = j.createWebClient(); + wc.setThrowExceptionOnFailingStatusCode(false); + HtmlPage configPage = wc.goTo("job/" + project.getName() + "/build?delay=0sec"); + DomNodeList<DomElement> nodes = configPage.getElementsByTagName("td"); + DomElement renderedParameterElement = null; + for (DomElement elem : nodes) { + if (elem.getAttribute("class").contains("setting-name")) { + renderedParameterElement = elem; + break; + } + } + assertNotNull("Could not locate rendered parameter element", renderedParameterElement); + String renderedText = renderedParameterElement.getFirstChild().asXml(); + assertNotEquals("XSS string was not escaped!", xssString, renderedText); + assertEquals("XSS string was not escaped!", "<img src=x onerror=alert(123)>", renderedText.trim()); + } +}
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-9jv5-wf44-8vfmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-2289ghsaADVISORY
- www.openwall.com/lists/oss-security/2020/10/08/5ghsamailing-listx_refsource_MLISTWEB
- github.com/jenkinsci/active-choices-plugin/commit/59bbd4a963dbf1aba5ca9699a913b06d4b5182feghsaWEB
- www.jenkins.io/security/advisory/2020-10-08/ghsax_refsource_CONFIRMWEB
News mentions
1- Jenkins Security Advisory 2020-10-08Jenkins Security Advisories · Oct 8, 2020