VYPR
Moderate severityNVD Advisory· Published Jan 24, 2023· Updated Apr 2, 2025

CVE-2023-24428

CVE-2023-24428

Description

A cross-site request forgery (CSRF) vulnerability in Jenkins Bitbucket OAuth Plugin 0.12 and earlier allows attackers to trick users into logging in to the attacker's account.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A CSRF vulnerability in Jenkins Bitbucket OAuth Plugin 0.12 and earlier allows attackers to trick users into logging in to the attacker's Bitbucket account.

## What is the vulnerability? CVE-2023-24428 is a cross-site request forgery (CSRF) vulnerability in the Jenkins Bitbucket OAuth Plugin, versions 0.12 and earlier, as described in the Jenkins Security Advisory [1] and the NVD entry [4]. The plugin implements OAuth authentication for Bitbucket users, but its login flow lacked a state parameter to prevent CSRF attacks [2]. This allows an attacker to trick a Jenkins user into logging in with the attacker's Bitbucket account instead of their own.

## How is it exploited? The attacker crafts a malicious URL that initiates the OAuth login flow with the attacker's Bitbucket OAuth credentials. When a logged-in Jenkins user clicks this link, the plugin processes the request and completes the OAuth handshake using the attacker's consumer key and secret, ultimately logging the user into the attacker's Bitbucket account. No authentication is required for the attacker; the victim must be authenticated to Jenkins and has to click the crafted link.

Impact

Successful exploitation causes the victim's Jenkins session to be associated with the attacker's Bitbucket identity. If the Jenkins instance uses Bitbucket team membership for authorization (e.g., via matrix-based security), the attacker may gain access to resources or perform actions with the victim's permissions, but under the attacker's account [2]. This could lead to unauthorized access to projects, builds, and credentials.

Mitigation

The vulnerability is fixed by adding a cryptographically random state parameter to the OAuth authorization request, as seen in commit a927a8f [3]. The Jenkins Security Advisory recommends upgrading to a version that includes this fix [1]. Users should apply the updated plugin to prevent CSRF attacks.

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.

PackageAffected versionsPatched versions
org.jenkins-ci.plugins:bitbucket-oauthMaven
< 0.130.13

Affected products

3

Patches

1
a927a8ff2e06

[SECURITY-2981] fix CSRF vulnerability in OAuth flow

2 files changed · +13 3
  • src/main/java/org/jenkinsci/plugins/api/BitbucketApiService.java+2 2 modified
    @@ -46,8 +46,8 @@ public Token createRquestToken() {
             return service.getRequestToken();
         }
     
    -    public String createAuthorizationCodeURL(Token requestToken) {
    -        return service.getAuthorizationUrl(requestToken);
    +    public String createAuthorizationCodeURL(Token requestToken, String state) {
    +        return service.getAuthorizationUrl(requestToken) + "&state=" + state;
         }
     
         public Token getTokenByAuthorizationCode(String code, Token requestToken) {
    
  • src/main/java/org/jenkinsci/plugins/BitbucketSecurityRealm.java+11 1 modified
    @@ -12,6 +12,7 @@
     import org.acegisecurity.userdetails.UserDetails;
     import org.acegisecurity.userdetails.UserDetailsService;
     import org.acegisecurity.userdetails.UsernameNotFoundException;
    +import org.apache.commons.lang.RandomStringUtils;
     import org.apache.commons.lang.StringUtils;
     import org.jenkinsci.plugins.api.BitbucketApiService;
     import org.jenkinsci.plugins.api.BitbucketGroup;
    @@ -45,6 +46,7 @@
     
     public class BitbucketSecurityRealm extends SecurityRealm {
     
    +    private static final String STATE_ATTRIBUTE = BitbucketSecurityRealm.class.getName() + ".state";
         private static final String REFERER_ATTRIBUTE = BitbucketSecurityRealm.class.getName() + ".referer";
         private static final Logger LOGGER = Logger.getLogger(BitbucketSecurityRealm.class.getName());
     
    @@ -117,6 +119,8 @@ public void setSecretClientSecret(Secret secretClientSecret) {
         public HttpResponse doCommenceLogin(StaplerRequest request, @Header("Referer") final String referer)
                 throws IOException {
     
    +        String state = RandomStringUtils.random(64, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~");
    +        request.getSession().setAttribute(STATE_ATTRIBUTE, state);
             request.getSession().setAttribute(REFERER_ATTRIBUTE, referer);
     
             Jenkins jenkins = Jenkins.getInstance();
    @@ -131,17 +135,23 @@ public HttpResponse doCommenceLogin(StaplerRequest request, @Header("Referer") f
     
             BitbucketApiService bitbucketApiService = new BitbucketApiService(clientID, getSecretClientSecret().getPlainText(), callback);
     
    -        return new HttpRedirect(bitbucketApiService.createAuthorizationCodeURL(null));
    +        return new HttpRedirect(bitbucketApiService.createAuthorizationCodeURL(null, state));
         }
     
         public HttpResponse doFinishLogin(StaplerRequest request) throws IOException {
             String code = request.getParameter("code");
    +        String state = request.getParameter("state");
     
             if (StringUtils.isBlank(code)) {
                 LOGGER.log(Level.SEVERE, "doFinishLogin() code = null");
                 return HttpResponses.redirectToContextRoot();
             }
     
    +        if (state == null || !StringUtils.equals(state, (String) request.getSession().getAttribute(STATE_ATTRIBUTE))) {
    +            LOGGER.log(Level.SEVERE, "doFinishLogin() invalid state parameter");
    +            return HttpResponses.redirectToContextRoot();
    +        }
    +
             String rawClientSecret = getSecretClientSecret().getPlainText();
     
             Token accessToken = new BitbucketApiService(clientID, rawClientSecret).getTokenByAuthorizationCode(code, null);
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

1