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

   ### Advisory Details
   
   **Title**: Vulnerability in `Script.java` Command Sanitization Allows 
Exposure of Plaintext Ceph RBD Storage Credentials in Logs
   
   **Description**:
   
   Apache CloudStack uses the core utility class 
`com.cloud.utils.script.Script` to execute external system processes (such as 
`qemu-img` conversion, block device mapping, and shell operations). To prevent 
sensitive access keys or passwords from appearing in console and file logging, 
`Script.java` implements a custom command line builder (`buildCommandLine`) 
that obscures arguments using a helper method 
`sanitizeRbdFileFormatCmdParameter`.
   
   However, the current implementation of `sanitizeRbdFileFormatCmdParameter` 
contains several logic vulnerabilities that allow attackers/users to bypass 
masking entirely under three common operational scenarios:
   1. **URI-based Ceph Credentials:** Storage network URI patterns (e.g. 
`rbd://username:password@host/pool`) do not contain the substring `"key="` and 
use a scheme starting with `"rbd://"` rather than `"rbd:"`. This skips the 
sanitization conditions entirely.
   2. **Bash Execution Wrappers:** If commands are executed via standard shell 
wrappers (e.g. `["/bin/bash", "-c", "qemu-img convert ... 
rbd:pool/image:key=secret"]`), the evaluated argument string begins with the 
shell prefix rather than `"rbd:"`. This triggers the prefix constraint 
`!cmd.startsWith("rbd:")` and leaves the plaintext key unmasked.
   3. **Multiple key= Occurrences:** The method splits arguments using 
`cmd.split("key=")` and exits immediately if `tokens.length != 2`. If a 
Base64-encoded Ceph key contains the substring `key=` or other properties 
introduce multiple `key=` elements, the length constraint is violated, and the 
raw plaintext key is logged to disk.
   
   ### Summary
   
   An information leakage vulnerability in Apache CloudStack's central process 
execution logging utility (`com.cloud.utils.script.Script`) allows plaintext 
storage pool credentials (usernames and passwords/keys) to be logged in the 
clear when Ceph RBD connection options, network URIs, or multiple key options 
are executed as shell commands.
   
   ### Details
   
   The vulnerability lies in the implementation of the private 
`sanitizeRbdFileFormatCmdParameter` method in 
`utils/src/main/java/com/cloud/utils/script/Script.java`:
   
   ```java
       private boolean sanitizeRbdFileFormatCmdParameter(String cmd, 
StringBuilder builder) {
           if (StringUtils.isEmpty(cmd) || !cmd.startsWith("rbd:") || 
!cmd.contains("key=")) {
               return false;
           }
   
           String[] tokens = cmd.split("key=");
           if (tokens.length != 2) {
               return false;
           }
           ...
   ```
   
   - **Prefix Bypass:** If `cmd` is a standard RBD network URI 
(`rbd://user:pass@host/pool`), it does not contain the substring `"key="` and 
is processed as a standard unsanitized parameter, outputting the embedded 
credentials in plaintext.
   - **Shell Wrapper Bypass:** When running commands via helper utilities (like 
`/bin/bash -c "..."`), the entire shell string is treated as a single argument. 
Because this parameter starts with `/bin/bash` or `qemu-img` instead of 
`"rbd:"`, the startsWith check fails, outputting the plaintext password to the 
log.
   - **Split Count Bypass:** If a Base64-encoded Ceph key or other parameters 
within the command string introduce multiple `key=` substrings, `tokens.length` 
exceeds `2`, skipping the sanitization process entirely and printing the 
plaintext key.
   
   ### PoC
   
   #### Prerequisites
   
   - Java Development Kit (JDK 11 or higher).
   - Maven 3.x for executing JUnit test validations.
   - Python 3.x for running integration simulation scripts.
   
   #### Reproduction Steps
   
   1. Download the automated logical verification script from: 
[verification_test.py](https://gist.github.com/YLChen-007/4d8ecc1d6041177bac3d12da5a30becd)
   2. Download the scientific control group script from: 
[control-normal_sanitization.py](https://gist.github.com/YLChen-007/756c21564a106bc60c27e521f1b7674f)
   3. Execute the automated logical verification script:
      ```bash
      python3 verification_test.py
      ```
   4. Execute the scientific control group script to confirm normal 
sanitization remains functional:
      ```bash
      python3 control-normal_sanitization.py
      ```
   5. Alternatively, run the built-in repository unit tests which demonstrate 
the exact unpatched variant behavior:
      ```bash
      mvn test -pl utils -Dtest=ScriptTest
      ```
   
   ### Log of Evidence
   
   ```
   =========================================================================
   [*] Running RbdLogLeak Defect Variant Verification
   =========================================================================
   [*] Stage 1: Attempting to connect to running CloudStack Management Server...
   [!] CloudStack Management Server is offline (Expected in isolated 
environment).
   [*] Switching to Academic/Logical Code-Path Verification...
   
   --- Flow 1: RBD URI with Credentials ---
   Original constructed command:
     qemu-img convert 
rbd://cloudstack:AQD-hJxklW1RGRAAA56oHGN6d-WPDLss2b05Cw==@ceph-mon:6789/pool/volume
   Logged command from Script.java:
     qemu-img convert 
rbd://cloudstack:AQD-hJxklW1RGRAAA56oHGN6d-WPDLss2b05Cw==@ceph-mon:6789/pool/volume
   🔴 [DEFECT-CONFIRMED] Plaintext Ceph secret is fully exposed in Flow 1 log 
output!
   
   --- Flow 2: RBD connection options in Bash Script Execution ---
   Original constructed command:
     /bin/bash -c qemu-img convert -O qcow2 
rbd:pool/image:key=supersecretpass999:auth_supported=cephx /tmp/output.qcow2
   Logged command from Script.java:
     /bin/bash -c qemu-img convert -O qcow2 
rbd:pool/image:key=supersecretpass999:auth_supported=cephx /tmp/output.qcow2
   🔴 [DEFECT-CONFIRMED] Plaintext Ceph secret is fully exposed in Flow 2 log 
output!
   
   --- Flow 3: RBD key= option with multiple occurrences ---
   Original constructed command:
     qemu-img convert rbd:pool/image:key=secret1:some_option=key=secret2
   Logged command from Script.java:
     qemu-img convert rbd:pool/image:key=secret1:some_option=key=secret2
   🔴 [DEFECT-CONFIRMED] Plaintext Ceph secret is fully exposed in Flow 3 log 
output!
   
   =========================================================================
   RESULT: DEFECT-CONFIRMED (TRUE POSITIVE)
   =========================================================================
   
   =========================================================================
   [*] Running RbdLogLeak Defect Control Test (Scientific Control Group)
   =========================================================================
   
   --- Control Group: Normal Ceph RBD parameter string ---
   Original constructed command:
     rbd:pool/image:key=my-ceph-secret-key:auth_supported=cephx
   Logged command from Script.java:
     rbd:pool/image:key=******:auth_supported=cephx
   🟢 [CONTROL-PASSED] Plaintext Ceph secret was successfully masked to 
'key=******'.
   =========================================================================
   RESULT: CONTROL-PASSED
   =========================================================================
   ```
   
   ### Impact
   
   - **Vulnerability Category:** Exposure of Sensitive Information to an 
Unauthorized Actor via Log Files.
   - **Assets Compromised:** Central primary storage / Ceph RBD storage 
clusters.
   - **Exploitation Impact:** Leaking master Ceph storage credentials into the 
application log allows anyone with log file access (such as system 
administrators, SOC analysts, log aggregator databases) to obtain full 
administrative control over the entire Ceph cluster. An attacker can read, 
modify, or delete virtual machine templates, primary disk files, system 
volumes, snapshots, and customer raw databases.
   
   ### Affected products
   
   - **Ecosystem**: maven
   - **Package name**: org.apache.cloudstack:cloud-utils
   - **Affected versions**: `<= 4.22.1.0`
   - **Patched versions**: <None>
   
   ### Severity
   
   - **Severity**: High
   - **Vector string**: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
   
   ### Weaknesses
   
   - **CWE**: CWE-532: Insertion of Sensitive Information into Log File
   
   ### Occurrences
   
   | Permalink | Description |
   | :--- | :--- |
   | 
[https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/utils/src/main/java/com/cloud/utils/script/Script.java#L202-L221](https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/utils/src/main/java/com/cloud/utils/script/Script.java#L202-L221)
 | The vulnerable helper `sanitizeRbdFileFormatCmdParameter` containing fragile 
startsWith prefix and token split constraints that ignore different URI schemes 
and shell wrapper sub-commands. |
   | 
[https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/utils/src/main/java/com/cloud/utils/script/Script.java#L166-L186](https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/utils/src/main/java/com/cloud/utils/script/Script.java#L166-L186)
 | The `buildCommandLine` execution parameters builder that calls 
`sanitizeRbdFileFormatCmdParameter` without robust token extraction or 
regex-based masking of secrets. |


-- 
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