CVE-2021-21616
Description
Jenkins Active Choices Plugin 2.5.2 and earlier has a stored XSS vulnerability due to missing escaping of reference parameter values, allowing attackers with Job/Configure permission to execute arbitrary JavaScript.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins Active Choices Plugin 2.5.2 and earlier has a stored XSS vulnerability due to missing escaping of reference parameter values, allowing attackers with Job/Configure permission to execute arbitrary JavaScript.
Vulnerability
Description
Jenkins Active Choices Plugin versions 2.5.2 and earlier do not escape reference parameter values, leading to a stored cross-site scripting (XSS) vulnerability [2][3]. The plugin's reactive reference parameters are intended to display dynamic HTML, but the lack of proper output encoding allows injected scripts to be executed when users view job configurations or build parameters [1].
Exploitation
An attacker must have Job/Configure permission to modify a job's parameter definitions. By injecting malicious HTML or JavaScript into a reference parameter value, the script is stored and later rendered without sanitization in the Jenkins UI [3]. The attack does not require any additional privileges, making it exploitable by any user who can configure jobs.
Impact
Successful exploitation allows the attacker to execute arbitrary JavaScript in the context of victims' browsers, potentially leading to session hijacking, credential theft, or other malicious actions within Jenkins [2]. Since the XSS is stored, every user who accesses the affected job configuration or build parameters is at risk.
Mitigation
Active Choices Plugin version 2.5.3 escapes reference parameter values to prevent XSS [3][4]. Users should upgrade immediately. No workarounds are available for earlier versions.
- 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.
- NVD - CVE-2021-21616
- Jenkins Security Advisory 2021-02-24
- [SECURITY-2192] · jenkinsci/active-choices-plugin@d0b768c
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.3 | 2.5.3 |
Affected products
2- Range: unspecified
Patches
1d0b768c18baf[SECURITY-2192]
3 files changed · +126 −1
README.md+2 −0 modified@@ -571,6 +571,8 @@ by plug-ins, API or scripts. Please see [this issue](https://issues.jenkins-ci.o ### Version 2.5.2 (2021/02/21) 1. [JENKINS-62806](https://issues.jenkins.io/browse/JENKINS-62806): active-choices plugin may break with tables-to-divs. +2. [SECURITY-1954 - CVE-2021-????](https://www.jenkins.io/security/advisory/???): Possible XSS in DynamicReference +parameter due to the referenced parameter name not being escaped. ### Version 2.5.1 (2020/10/17)
src/main/java/org/biouno/unochoice/AbstractCascadableParameter.java+3 −1 modified@@ -35,6 +35,8 @@ import org.kohsuke.stapler.bind.JavaScriptMethod; import org.kohsuke.stapler.json.JsonHttpResponse; +import hudson.Util; + /** * Base class for cascadable parameters, providing basic and utility methods. * @@ -161,7 +163,7 @@ public String[] getReferencedParametersAsArray() { for (String value : array) { value = value.trim(); if (StringUtils.isNotBlank(value)) { - list.add(value); + list.add(Util.escape(value)); } } return list.toArray(new String[0]);
src/test/java/org/biouno/unochoice/jenkins_cert_2192/TestDynamicReferenceXss.java+121 −0 added@@ -0,0 +1,121 @@ +/* + * 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_2192; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; + +import org.biouno.unochoice.AbstractCascadableParameter; +import org.biouno.unochoice.ChoiceParameter; +import org.biouno.unochoice.DynamicReferenceParameter; +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.Issue; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.JenkinsRule.WebClient; +import org.xml.sax.SAXException; + +import com.gargoylesoftware.htmlunit.CollectingAlertHandler; + +import hudson.model.FreeStyleProject; +import hudson.model.ParametersDefinitionProperty; + +/** + * Prevent a case where a DynamicReference parameter with a referenced + * parameter name equal to {@code "+alert(123)+"} results in a possible + * XSS case. + * + * @since 2.5.2 + * @see {@link hudson.Util#escape} + */ +@Issue("2192") +public class TestDynamicReferenceXss { + + @Rule + public JenkinsRule j = new JenkinsRule(); + + /** + * Tests that a {@code DynamicReference} reference parameter name is sanitized against XSS. + * @throws IOException if it fails to load the script + * @throws SAXException if the XML is malformed + */ + @Test + public void testChoicesParameterXss() throws IOException, SAXException { + FreeStyleProject project = j.createFreeStyleProject(); + String scriptText = String.format("return ['OK']"); + SecureGroovyScript secureScript = new SecureGroovyScript(scriptText, true, null); + GroovyScript script = new GroovyScript(secureScript, secureScript); + + final String xssString = "\"+alert(123)+\""; + + DynamicReferenceParameter parameter = new DynamicReferenceParameter( + "PARAMETER_NAME", + "Description", + "random-name", + script, + ChoiceParameter.PARAMETER_TYPE_RADIO, + xssString, + false); + project.addProperty(new ParametersDefinitionProperty(parameter)); + project.save(); + + final CollectingAlertHandler alertHandler = new CollectingAlertHandler(); + final WebClient wc = j.createWebClient(); + wc.setThrowExceptionOnFailingStatusCode(false); + wc.setAlertHandler(alertHandler); + + wc.goTo("job/" + project.getName() + "/build?delay=0sec"); + final List<String> alertmsgs = alertHandler.getCollectedAlerts(); + + assertEquals("You got a JS alert, look out for XSS!", 0, alertmsgs.size()); + } + + /** + * Test that the reference parameter value is escaped. + */ + @Test + public void testGetReferencedParametersAsArray() { + String scriptText = String.format("return ['OK']"); + SecureGroovyScript secureScript = new SecureGroovyScript(scriptText, true, null); + GroovyScript script = new GroovyScript(secureScript, secureScript); + final String xssString = "\"+alert(123)+\""; + AbstractCascadableParameter parameter = new DynamicReferenceParameter( + "PARAMETER_NAME", + "Description", + "random-name", + script, + ChoiceParameter.PARAMETER_TYPE_RADIO, + xssString, + false); + + String[] parameters = parameter.getReferencedParametersAsArray(); + String[] expected = new String[] {""+alert(123)+""}; + assertArrayEquals("Your reference parameter name was not escaped, look out for XSS!", expected, parameters); + } +}
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-4f6x-g5vh-8jm5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21616ghsaADVISORY
- www.openwall.com/lists/oss-security/2021/02/24/3ghsamailing-listx_refsource_MLISTWEB
- github.com/jenkinsci/active-choices-plugin/commit/d0b768c18bafd812b52fe579def8b14e26033ec9ghsaWEB
- www.jenkins.io/security/advisory/2021-02-24/ghsax_refsource_CONFIRMWEB
News mentions
1- Jenkins Security Advisory 2021-02-24Jenkins Security Advisories · Feb 24, 2021