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]