CVE-2023-41935 - Exploiting Timing Attacks in Jenkins Azure AD Plugin (396.v86ce29279947 and Earlier)
Jenkins is a widely used automation server for building, testing, and deploying software projects. With countless plugins for integration, security is always a top concern. One plugin, Azure AD Plugin, makes it easy to hook Jenkins up to Azure Active Directory for authentication and authorization. But in September 2023, a new vulnerability was identified in this plugin—CVE-2023-41935—that could let attackers bypass Jenkins protections through a timing side-channel attack.
In this long read, we’ll break down the flaw, how an attacker might exploit it, and strategies for mitigation. Real code snippets and reference links included so you can understand all the angles.
What is CVE-2023-41935?
CVE-2023-41935 is a flaw in the Jenkins Azure AD Plugin (versions 396.v86ce29279947 and earlier, except 378.380.v545b_1154b_3fb_) that potentially allows attackers to find valid CSRF tokens by exploiting timing differences during comparison.
> Technical Summary:
> The vulnerable plugin version does not use a constant-time function to compare the submitted CSRF nonce with the expected value. Instead, it compares the values in a way that reveals how many prefix characters match, based on how long the check takes. Attackers can use this to statistically deduce the correct value, potentially enabling CSRF attacks.
Why Does Timing Matter?
When you check security-sensitive values like passwords or tokens, you want the comparison to take the same amount of time regardless of whether only the first character matches or all characters match. This is called constant-time comparison.
If the code checks 'a' == 'a', then 'ab' == 'ab', it might return a match fast if the first letter is wrong, but take a little longer as more letters are correct. A smart attacker can measure that difference (“timing side-channel”) and guess the value one character at a time.
Here’s a generic example of what *not* to do
// BAD: Not constant-time
public boolean isValidNonce(String submitted, String expected) {
return submitted.equals(expected); // Java's equals() is NOT constant-time
}
Many common string comparison methods (like String.equals()) bail out as soon as a character mismatches, causing the function to return faster for wrong guesses, and slower as guesses get better.
Here’s how Java code can use a constant-time comparison
// GOOD: Constant-time comparison
public static boolean constantTimeEquals(String a, String b) {
if (a == null || b == null || a.length() != b.length()) return false;
int result = ;
for (int i = ; i < a.length(); i++) {
result |= a.charAt(i) ^ b.charAt(i);
}
return result == ;
}
This code always runs the same number of operations, regardless of how many characters match, preventing attackers from learning any characters based on timing.
Exploit Scenario
Attacker’s Goal: Find out the correct CSRF nonce and use it to impersonate a legitimate request, bypassing Jenkins’s CSRF protection.
1. Measuring Response Time
The attacker sends a request with a guessed nonce.
Guess 3: C000... [response in 27ms] ← Longest!
The attacker notes that guess C000... took the longest, suggesting “C” was a correct first character.
CC00... [26ms]
Suppose CB00... was slowest, so now the second character is likely “B”.
3. Full Nonce Extraction
By doing this for every position, the attacker can deduce the full CSRF token in a small number of tries. With the token, they can craft valid POST requests that Jenkins will accept, potentially leading to account compromise or arbitrary actions, especially if the attacker can trick administrators into clicking malicious links.
References & More Reading
- Jenkins Plugin Security Advisory September 2023
- Azure AD Plugin Changelog
- OWASP: Timing Attack
- Original CVE Entry
Update the Plugin:
If you’re running Azure AD Plugin 396.v86ce29279947 or earlier, update now. The patch is included in later versions.
> *Fixed as of release 402.veb64d2682614*
Mitigation Workaround:
If you can't upgrade immediately, limit who can access Jenkins, restrict external network access, and avoid being logged into Jenkins when browsing other sites.
Check for Similar Patterns:
This style of vulnerability (timing side-channels in comparisons) can affect any authentication, token, or key management logic!
Final Thoughts
CVE-2023-41935 is a classic example of how small failures in code can lead to big security problems. When comparing secrets, use constant-time functions, especially in authentication and authorization code. If you’re using Jenkins Azure AD Plugin, check your version and update today.
Exclusive Content by AI Security Team, 2024
For questions or help, check out the official Jenkins Security page or explore Jenkins Community forums.
Timeline
Published on: 09/06/2023 13:15:10 UTC
Last modified on: 09/11/2023 17:54:37 UTC