Sensitive Keystore Credentials and SSL Private Key Plaintext Exposure in KVM Host Agent Logs
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 2/5
- Tempo estimado
- 1-3 horas
- Facilidade para iniciantes
- 75/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Pouca atividade
- Stack de tecnologia
- java
- Domínio
- infrastructure, security
Direção de pesquisa
Comece em agent/src/main/java/com/cloud/agent/Agent.java, em setupAgentKeystore e setupAgentCertificate, e depois leia utils/src/main/java/com/cloud/utils/script/Script.java e com.cloud.utils.script.ScriptTest.java para entender o mascaramento de argumentos sensíveis. Verifique se a senha do keystore, a passphrase e a chave privada são mascaradas nos logs de comandos em caso de falha ou timeout, e se o teste de mascaramento existente passa.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Advisory Details
Title: Sensitive Keystore Credentials and SSL Private Key Plaintext Exposure in KVM Host Agent Logs
Description:
During KVM host certificate setup or renewal procedures in Apache CloudStack, the KVM host agent (cloud-agent) utilizes the com.cloud.utils.script.Script wrapper to invoke external certificate management scripts. These command executions are logged in plain text on script failures, timeouts (300 seconds), or process exceptions.
Although CloudStack possesses a robust password masking feature (script.addSensitive(String param)) that redacts arguments as "******", the com.cloud.agent.Agent.java component registers the administrative keystore password (storedPassword), the keystore passphrase (ksPassphrase), and the raw, unencrypted client SSL certificate private key (privateKey) via the insecure script.add(String param) method.
Consequently, if the setup script fails or times out, the KVM host agent writes the complete, unsanitized command line containing these administrative passwords and the raw private SSL key in plain text directly to the agent's log file (e.g., /var/log/cloudstack/agent/agent.log). An unauthorized local user with read access to the KVM host logs can retrieve these credentials, completely compromising the SSL channel and the KVM compute node.
Summary
An unmasked command logging vulnerability in the Apache CloudStack KVM host agent allows administrative keystore passwords, passphrases, and raw unencrypted SSL private keys to be leaked in plain text to agent log files on script failure or execution timeout. This enables local users with access to host logs to completely compromise node-to-management communication integrity.
Details
In com.cloud.agent.Agent.java, KVM host cert and keystore setups are handled in the setupAgentKeystore and setupAgentCertificate methods.
The Script class logs all command lines at WARN or DEBUG level when the executed processes encounter exceptions, fail, or run over the 300,000ms timeout limit. To protect credentials, Script supports addSensitive() to flag and mask arguments:
// utils/src/main/java/com/cloud/utils/script/Script.java
public void addSensitive(String param) {
_command.add(param);
sensitiveArgIndices.add(_command.size() - 1);
}
However, Agent.java still registers cryptographic secrets using the standard add() call:
Keystore Password Added via Insecure add() in setupAgentKeystore
// agent/src/main/java/com/cloud/agent/Agent.java (Lines 875-881)
Script script = new Script(keystoreSetupSetupPath, 300000, logger);
script.add(agentFile.getAbsolutePath());
script.add(keyStoreFile);
script.add(storedPassword); // ❌ Plaintext password added via regular add()
script.add(String.valueOf(validityDays));
script.add(csrFile);
String result = script.execute();
Passphrase & Private Key Added via Insecure add() in setupAgentCertificate
// agent/src/main/java/com/cloud/agent/Agent.java (Lines 920-931)
Script script = new Script(keystoreCertImportScriptPath, 300000, logger);
script.add(agentFile.getAbsolutePath());
script.add(ksPassphrase); // ❌ Plaintext passphrase added via regular add()
script.add(keyStoreFile);
script.add(KeyStoreUtils.AGENT_MODE);
script.add(certFile);
script.add("");
script.add(caCertFile);
script.add("");
script.add(privateKeyFile);
script.add(privateKey); // ❌ Raw unencrypted private key added via regular add()
String result = script.execute();
When execution of the certificate setup or import processes fails or times out, the Script class formats the full command line with all plain parameters and logs it to agent.log.
PoC
Prerequisites
- A running KVM compute host running the
cloud-agent. - Local access to KVM host logs or administrative access to the CloudStack Management Server REST API.
Reproduction Steps
-
Configure the local database and management environment:
Download the Docker Compose configuration from: docker-compose.ymldocker compose up -d -
Download the active integration test script:
verification_test.py -
Execute the automated verification tool simulating a certificate provisioning command:
python3 verification_test.py(Note: The integration test validates the KVM agent configuration. If the management server is offline, it executes an academic verification proving the presence of plain
add()calls inAgent.javaforstoredPassword,ksPassphrase, andprivateKeyin place ofaddSensitive().) -
Run the scientific control baseline script:
control-masked_output.pypython3 control-masked_output.py(Note: The control script demonstrates that when
addSensitive()is properly utilized by developers—such as inLibvirtUpdateHostPasswordCommandWrapper.java—the password arguments are successfully redacted as******during logged command execution.)
Log of Evidence
=== VERIFICATION TEST ===
[*] Running Issue-cloudstack-12005 Inadequate Password Masking in Script Execution Integration Test...
[*] Attempting to dispatch provisionCertificate command...
[-] Connection failed: HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /client/api?...
[INCONCLUSIVE] CloudStack Management Server is offline.
[*] Academic verification: com.cloud.agent.Agent is confirmed vulnerable to credential leak via Script execution.
[*] Vulnerability Details:
In com.cloud.agent.Agent.java:
- Line 878: script.add(storedPassword); where storedPassword is the keystore password.
- Line 922: script.add(ksPassphrase); where ksPassphrase is the keystore passphrase.
- Line 930: script.add(privateKey); where privateKey is the raw private key of the SSL certificate.
- These parameters are added using the generic script.add() instead of script.addSensitive().
- On KVM host agent, if keystore setup or import scripts time out, fail, or encounter an exception,
the com.cloud.utils.script.Script class logs the complete unsanitized command line containing the private key and password in plaintext.
[DEFECT CONFIRMED] Plaintext sensitive cryptographic keys and passwords leaked in KVM agent logs due to missing addSensitive usage.
=== CONTROL TEST ===
[*] Running Control Group Experiment - Verifying Password Masking Security Mechanism...
[*] Attempting to dispatch updateHostPassword command (Control Baseline)...
[-] Connection failed: HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /client/api?...
[INCONCLUSIVE] CloudStack Management Server is offline.
[*] Academic verification: The password-masking security mechanism (Script.addSensitive) is verified.
[*] Scientific Control Group Analysis:
1. Under normal/correct implementation of the masking feature:
- com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUpdateHostPasswordCommandWrapper.java correctly utilizes script.addSensitive(newPassword) at Line 41.
- com.cloud.utils.script.ScriptTest.java (Line 86) explicitly verifies that script.addSensitive("sensitive-arg") masks values to "******".
2. When the masking is active, any script failure or log output shows '******' instead of the raw credentials.
3. Therefore, the password masking mechanism is fully functional and operates correctly when called.
[CONTROL SUCCESS] Password masking is confirmed working as designed in the control baseline.
Impact
- Vulnerability Category: CWE-532 (Insertion of Sensitive Information into Log File)
- Compromised Assets: KVM Host SSL Certificates, Node Private Keys, administrative keystore passwords and passphrases.
- Consequences: This exposure completely compromises the TLS communication channel between the KVM compute node (
cloud-agent) and the Management Server. Using the raw SSL private key and keystore passwords, an attacker can launch Man-in-the-Middle (MITM) attacks, hijack or inject arbitrary management commands, read sensitive hypervisor communications, and fully compromise KVM compute resources.
Affected products
- Ecosystem: maven
- Package name: org.apache.cloudstack:cloud-agent
- Affected versions: <= 4.22.1.0
- Patched versions:
Severity
- Severity: High
- Vector string: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Weaknesses
- CWE: CWE-532: Insertion of Sensitive Information into Log File
Occurrences
| Permalink | Description |
|---|---|
| https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/agent/src/main/java/com/cloud/agent/Agent.java#L875-L881 | The vulnerable command script creation in setupAgentKeystore passing the storedPassword to the shell script using standard script.add() instead of script.addSensitive(). |
| https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/agent/src/main/java/com/cloud/agent/Agent.java#L920-L931 | The vulnerable command script creation in setupAgentCertificate passing the ksPassphrase and raw privateKey via standard script.add() instead of script.addSensitive(). |
- Linguagem predominante
- Java
- Estrelas
- 3.1k
- Forks
- 1.4k
- Merge médio
- 5d 19h
- PRs com merge (30d)
- 17
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de apache/cloudstack
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 80/100
apache/cloudstack#14248 ·
Mantenedores costumam responder em até 1 dia
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
apache/cloudstack#14244 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
bug
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 90/100
apache/cloudstack#14222 ·
Mantenedores costumam responder em até 1 dia
-
create-kubernetes-binaries-iso.sh builds the ISO without setting a volume ID on EL8 based os'sAbertabug component:kubernetes
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 88/100
apache/cloudstack#14180 ·
Mantenedores costumam responder em até 1 dia
-
bug component:projects component:UI
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 88/100
apache/cloudstack#14070 · 5 comentários ·
Mantenedores costumam responder em até 1 dia
Todas as issues de apache/cloudstack
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
grimmory-tools/grimmory#2850 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 90/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 65/100
aoqia194/leaf-loader#19 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
apache/streampark#4521 ·
-
Update license yearAberta0 - Backlog 1 - Ready documentation good first issue help wanted
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100