YLChen-007 opened a new issue, #12029:
URL: https://github.com/apache/cloudstack/issues/12029

   ## Summary
   
   A critical security vulnerability has been identified in the Apache 
CloudStack KVM agent security setup process where **randomly generated keystore 
passwords are logged in plaintext**. During the 
`LibvirtServerDiscoverer.setupAgentSecurity()` method execution, sensitive 
keystore passwords are exposed through SSH command logging in 
`SSHCmdHelper.sshExecuteCmdOneShot()`, compromising the security of 
agent-to-management-server communications.
   
   ## Vulnerability Details
   
   **Component:** `com.cloud.hypervisor.kvm.discoverer.LibvirtServerDiscoverer`
   - `setupAgentSecurity()`
   - `SSHCmdHelper.sshExecuteCmdWithResult()`
   - `SSHCmdHelper.sshExecuteCmdOneShot()`
   
   **Vulnerability Type:** Sensitive Information Disclosure / Password Exposure 
in Debug Logs (CWE-532, CWE-532)
   
   **Severity:** Critical
   
   **Affected Lines:**
   - Line 13: First keystore setup command containing `keystorePassword`
   - Line 35: Certificate import command containing `keystorePassword`
   
   ## Technical Description
   
   ### Vulnerability Flow
   
   #### 1. Password Generation and Password  Exposure (Line 205-221)
   
   The same password is used again in the certificate import command:
   
   ```java
   final SSHCmdHelper.SSHCmdResult setupCertResult = 
SSHCmdHelper.sshExecuteCmdWithResult(sshConnection,
           String.format("sudo /usr/share/cloudstack-common/scripts/util/%s " +
                           "/etc/cloudstack/agent/agent.properties %s " +  // ← 
keystorePassword exposed again
                           "/etc/cloudstack/agent/%s %s " +
                           "/etc/cloudstack/agent/%s \"%s\" " +
                           "/etc/cloudstack/agent/%s \"%s\" " +
                           "/etc/cloudstack/agent/%s \"%s\"",
                   KeyStoreUtils.KS_IMPORT_SCRIPT,
                   keystorePassword,                                        // 
← Line 35: Password in command
                   KeyStoreUtils.KS_FILENAME,
                   KeyStoreUtils.SSH_MODE,
                   KeyStoreUtils.CERT_FILENAME,
                   certificateCommand.getEncodedCertificate(),
                   KeyStoreUtils.CACERT_FILENAME,
                   certificateCommand.getEncodedCaCertificates(),
                   KeyStoreUtils.PKEY_FILENAME,
                   certificateCommand.getEncodedPrivateKey()));
   ```
   
   #### 3. Debug Logging Exposure
   
   Both commands are logged in `SSHCmdHelper.sshExecuteCmdOneShot()`:
   
   ```java
   public static SSHCmdResult sshExecuteCmdOneShot(com.trilead.ssh2.Connection 
sshConnection, String cmd) throws SshException {
       LOGGER.debug("Executing cmd: " + 
cmd.split(KeyStoreUtils.KS_FILENAME)[0]);  // ← Password logged here
       Session sshSession = null;
       try {
           sshSession = sshConnection.openSession();
           Thread.sleep(1000);
           
           if (sshSession == null) {
               throw new SshException("Cannot open ssh session");
           }
           // ... execution continues
       }
       // ...
   }
   ```
   
   ### Incomplete Sanitization Attempt
   
   The code attempts to sanitize by splitting on `KS_FILENAME` (likely 
`"agent.jks"`):
   
   ```java
   cmd.split(KeyStoreUtils.KS_FILENAME)[0]
   ```
   
   **However, this approach is fundamentally flawed:**
   
   The password appears **before** `agent.jks` in the command string, so it's 
included in the first split segment and **fully exposed in logs**.
   
   #### For Line 35 Command:
   ```bash
   # Original command:
   sudo .../keystore-import.sh /etc/.../agent.properties Xy9$mK2pL#4nQ7vR 
/etc/.../agent.jks ssh ...
   
   # After split on "agent.jks" and taking [0]:
   sudo .../keystore-import.sh /etc/.../agent.properties Xy9$mK2pL#4nQ7vR 
/etc/.../
   # ❌ Password is BEFORE the split point, so it's INCLUDED in the logged output
   ```
   
   Again, the password appears **before** the split point and is **fully 
exposed**.
   
   ## Root Cause Analysis
   
   1. **Flawed Sanitization Logic**: The `split(KeyStoreUtils.KS_FILENAME)[0]` 
approach assumes the password appears *after* the keystore filename, but the 
actual command structure places it *before*
   
   2. **Position-Dependent Vulnerability**: The sanitization logic is 
position-dependent but uses the wrong position marker
   
   3. **No Pattern-Based Redaction**: No regex or pattern matching to identify 
and mask password parameters
   
   4. **Debug Logging in Production**: Debug-level logging may be enabled in 
production environments, exposing sensitive data
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to