VYPR
Moderate severityNVD Advisory· Published Oct 6, 2021· Updated Aug 3, 2024

CVE-2021-21684

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.

PackageAffected versionsPatched versions
org.jenkins-ci.plugins:gitMaven
< 4.8.34.8.3

Affected products

2

Patches

1
5474cc942bfb

[SECURITY-2499]

https://github.com/jenkinsci/git-pluginOlivier LamySep 22, 2021via ghsa
2 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

News mentions

1