CVE-2021-21684
Description
Jenkins Git Plugin 4.8.2 and earlier does not escape the Git SHA-1 checksum parameters provided to commit notifications when displaying them in a build cause, resulting in a stored cross-site scripting (XSS) vulnerability.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jenkins Git Plugin 4.8.2 and earlier has a stored XSS vulnerability due to improper escaping of Git SHA-1 checksum parameters in commit notifications.
Vulnerability
Jenkins Git Plugin versions 4.8.2 and earlier do not escape the Git SHA-1 checksum parameters provided to commit notifications when displaying them in a build cause, leading to a stored cross-site scripting (XSS) vulnerability [1][2]. The affected parameter is the sha1 field in commit notifications, which is stored and later displayed without sanitization [3].
Exploitation
An attacker can send a crafted Git notification containing a malicious SHA-1 parameter to a Jenkins instance configured to use the Git Plugin [4]. The malicious payload is then stored and subsequently rendered in the build cause view, where it executes in the context of users viewing the build information [2]. No authentication is required if the commit notification endpoint is exposed; otherwise, the attacker must have access to trigger notifications [4].
Impact
Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of Jenkins, potentially leading to disclosure of sensitive information, credential theft, or further compromise of the Jenkins environment [2][4]. The attack is stored, meaning any user who accesses the affected build cause page is impacted.
Mitigation
The vulnerability is fixed in Git Plugin version 4.8.3, released on October 6, 2021 [3][4]. Users should upgrade to this version or later. As a workaround, administrators can restrict access to the commit notification endpoint or disable the plugin until an upgrade is applied [4].
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.jenkins-ci.plugins:gitMaven | < 4.8.3 | 4.8.3 |
Affected products
2- Jenkins project/Jenkins Git Pluginv5Range: unspecified
Patches
12 files changed · +37 −3
src/main/java/hudson/plugins/git/GitStatus.java+21 −3 modified@@ -18,6 +18,7 @@ import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -28,6 +29,7 @@ import jenkins.triggers.SCMTriggerItem; import org.apache.commons.lang.StringUtils; import static org.apache.commons.lang.StringUtils.isNotEmpty; + import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.URIish; import org.kohsuke.stapler.*; @@ -115,7 +117,10 @@ public HttpResponse doNotifyCommit(HttpServletRequest request, @QueryParameter(r @QueryParameter(required=false) String sha1) throws ServletException, IOException { lastURL = url; lastBranches = branches; - lastSHA1 = sha1; + if(StringUtils.isNotBlank(sha1)&&!SHA1_PATTERN.matcher(sha1.trim()).matches()){ + return HttpResponses.error(SC_BAD_REQUEST, new IllegalArgumentException("Illegal SHA1")); + } + lastSHA1 = cleanupSha1(sha1); lastBuildParameters = null; GitStatus.clearLastStaticBuildParameters(); URIish uri; @@ -316,6 +321,7 @@ public static class JenkinsAbstractProjectListener extends Listener { */ @Override public List<ResponseContributor> onNotifyCommit(String origin, URIish uri, String sha1, List<ParameterValue> buildParameters, String... branches) { + sha1 = cleanupSha1(sha1); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "Received notification from {0} for uri = {1} ; sha1 = {2} ; branches = {3}", new Object[]{StringUtils.defaultIfBlank(origin, "?"), uri, sha1, Arrays.toString(branches)}); @@ -594,15 +600,27 @@ public static class CommitHookCause extends Cause { public final String sha1; public CommitHookCause(String sha1) { - this.sha1 = sha1; + this.sha1 = cleanupSha1(sha1); } @Override public String getShortDescription() { - return "commit notification " + sha1; + return "commit notification " + cleanupSha1(sha1); } } + public static final Pattern SHA1_PATTERN = Pattern.compile("[a-fA-F0-9]++"); // we should have {40} but some compact sha1 + + public static final Pattern CLEANER_SHA1_PATTERN = Pattern.compile("[^a-fA-F0-9]"); + + /** + * @param sha1 the String to cleanup + * @return the String with all non hexa characters removed + */ + private static String cleanupSha1(String sha1){ + return sha1 == null?null:CLEANER_SHA1_PATTERN.matcher(sha1.trim()).replaceAll(""); + } + private static final Logger LOGGER = Logger.getLogger(GitStatus.class.getName()); private static final int MAX_REPORTED_CONTRIBUTORS = 10;
src/test/java/hudson/plugins/git/GitStatusTest.java+16 −0 modified@@ -23,6 +23,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.jgit.transport.URIish; +import org.kohsuke.stapler.HttpResponses; import org.mockito.Mockito; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -665,4 +666,19 @@ public void testDoNotifyCommitTriggeredHeadersLimited() throws Exception { assertEquals("URL: a Branches: master", this.gitStatus.toString()); } + + @Test + @Issue("SECURITY-2499") + public void testDoNotifyCommitWithWrongSha1Content() throws Exception { + setupProjectWithTrigger("a", "master", false); + + String content = "<img src=onerror=alert(1)>"; + + HttpResponse rsp = this.gitStatus.doNotifyCommit(requestWithNoParameter, "a", "master", content); + + HttpResponses.HttpResponseException responseException = ((HttpResponses.HttpResponseException) rsp); + assertEquals(IllegalArgumentException.class, responseException.getCause().getClass()); + assertEquals("Illegal SHA1", responseException.getCause().getMessage()); + + } }
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-gghc-g8cj-4vfvghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21684ghsaADVISORY
- www.openwall.com/lists/oss-security/2021/10/06/1ghsamailing-listx_refsource_MLISTWEB
- github.com/jenkinsci/git-plugin/commit/5474cc942bfba60927be629ff47fb41c38c66741ghsaWEB
- www.jenkins.io/security/advisory/2021-10-06/ghsax_refsource_CONFIRMWEB
News mentions
1- Jenkins Security Advisory 2021-10-06Jenkins Security Advisories · Oct 6, 2021