CVE-2025-24400 is a recently disclosed security vulnerability affecting Jenkins users who rely on the Eiffel Broadcaster Plugin, specifically versions 2.8. through 2.10.2. This flaw could allow attackers to publish signed events to RabbitMQ using _illegitimate credentials_, resulting in unauthorized actions or data leaks.
This post explains the vulnerability in simple language, provides a clear proof-of-concept, and walks through how attackers could exploit this issue in real-world Jenkins environments. You’ll also find references for more details and information on how to protect your Jenkins setup.
What is Jenkins Eiffel Broadcaster Plugin?
The Jenkins Eiffel Broadcaster Plugin is used to publish build events from Jenkins pipelines to an Eiffel event stream, often via message brokers like RabbitMQ. The plugin allows fine-grained control over event publishing, including signing events using stored Jenkins credentials.
Description of the Vulnerability
CVE-2025-24400 is a _credential confusion_ vulnerability.
Affected Versions: 2.8. - 2.10.2 (inclusive)
- Root Cause: When the plugin signs outgoing messages (events), it uses the credential ID as a cache key.
- Impact: Since Jenkins allows having credentials with the same ID in different stores (e.g., System, User, Folder-Level), an attacker with limited permissions (like Folder or User credentials permissions) could create a credential with the same ID as a system-wide, privileged credential.
- During signing, the plugin might use the attacker's credential for the cache, but actually sign the event using the privileged credential—all without authenticating the attacker.
Visual Summary
Attacker creates credential "rabbitmq-sign" in Folder.
Legitimate credential "rabbitmq-sign" exists in System store.
Jenkins plugin uses "rabbitmq-sign" as key in cache for signing.
Attacker publishes an event:
- Plugin looks up "rabbitmq-sign"
- Due to UUID collision, plugin accepts attacker's event
- Event is signed with legitimate rabbitmq-sign credentials
- Attacker's event is trusted by RabbitMQ consumers
> Result: Attacker can inject trusted events into the Eiffel event stream!
## Proof-of-Concept / Exploit Steps
Set ID to the same as the legitimate signing credential, e.g., rabbitmq-sign
3. Set any credential data (could be nonsense/private key to which the attacker has access).
Step 2: Trigger Event Publication
The attacker triggers a Jenkins job (pipeline) that publishes an event with the Eiffel Broadcaster Plugin, referencing rabbitmq-sign as the credential ID.
// Jenkinsfile (Pipeline script)
pipeline {
agent any
stages {
stage('Broadcast Eiffel Event') {
steps {
eiffelBroadcastEvent(
credentialsId: 'rabbitmq-sign',
eventType: 'eiffel_activity_triggered_event',
rabbitMqPublisherId: 'publisher-1',
data: [ ... ] // Attacker-controlled data
)
}
}
}
}
Step 3: Plugin Uses Wrong Credential For Cache Key
Internally, the plugin uses a credential cache, keyed only by credential ID, not by the _store_. Thus, it matches both the attacker's and legitimate credential as the same in-cache. But when signing, Jenkins’ credential resolution finds the legitimate credentials with the same ID (perhaps system credentials), not the attacker's, and signs the message with the real signing credential.
The plugin signs the attacker's event with organization-trusted credentials.
- Downstream systems (RabbitMQ consumers, Eiffel event receivers) cannot distinguish between valid and fake events, as the signature is legitimate.
Code Dive: Where the Issue Lives
Here’s a simplified code snippet (for illustration only—see the actual plugin source):
// Simulated example—it uses credential ID as a key
Map<String, Credential> credentialCache = ...;
Credential getCredential(String id) {
// Only keying by ID, not by context or store
if (!credentialCache.containsKey(id)) {
Credential c = doFindCredential(id); // Could find wrong-scope or same-id, different store
credentialCache.put(id, c);
}
return credentialCache.get(id);
}
- A proper cache should _namespace_ credentials by their context (store), reference, or UUID, not just their ID.
Mitigation & Fixes
The plugin maintainers released a fix:
- See plugin release notes: Eiffel Broadcaster Plugin changelog
Update to version 2.10.3 or later!
After the fix, the plugin uniquely identifies credentials by both ID and their context/store, preventing this attack.
Use meaningful, unique credential IDs to reduce ambiguity.
- Restrict who can create credentials in folders/users to trusted individuals only.
References
- Jenkins Security Advisory (CVE-2025-24400)
- Eiffel Broadcaster Plugin GitHub
- Jenkins Credentials plugin documentation
- Jenkins Plugin: Eiffel Broadcaster
Conclusion
CVE-2025-24400 is a classic example of how credential management quirks can lead to major security headaches, especially in complex tools like Jenkins. If your organization relies on the Eiffel Broadcaster Plugin, update now—before an attacker exploits credential-ID confusion to inject unauthorized, signed events into your event stream.
Timeline
Published on: 01/22/2025 17:15:13 UTC
Last modified on: 03/20/2025 14:15:23 UTC