apache / apache/cloudstack

Plaintext CIFS Storage Credential Leakage in Log Files and Exception Traces

Offen
#13,300 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
component:logging type:technical-debt
Vorherrschende Sprache
Java
Sterne
3.1k
Forks
1.4k
Ø Merge
6 T. 19 Std.
Gemergte PRs (30 T.)
32

Beschreibung

### Advisory Details

**Title**: Plaintext CIFS Storage Credential Leakage in Log Files and Exception Traces

**Description**:

### Summary

An information exposure vulnerability exists in Apache CloudStack where plaintext CIFS secondary storage credentials (including passwords) are logged directly to system files (such as `agent.log`, `vmops.log` or management server logs) and exception message traces. During the mounting, status checking, and automatic discovery phases of a CIFS storage pool containing sensitive query parameters (e.g. `cifs://host/share?user=foo&password=bar`), the application directly records the raw, unsanitized `URI` or `URL` objects, bypassing the standard log sanitization filters.

### Details

In CloudStack, the `NfsSecondaryStorageResource.java`, `LocalNfsSecondaryStorageResource.java`, and `SecondaryStorageDiscoverer.java` classes handle mounting and discovering secondary storage networks. The original patch for **Issue-cloudstack-8853** introduced `StringUtils.cleanString(extraOptions)` to scrub plaintext passwords from the parsed mount options log block. However, multiple critical logging paths print raw `URI.toString()` or `secUrl` strings without wrapping them in the sanitization mechanism.

Specifically:
- **SSVM Mounting Phase (`NfsSecondaryStorageResource.java`)**:
Raw `uri` and `secUrl` strings are formatted into logger warnings, debug logs, and exceptions when executing mount commands, creating directory structures, and throwing scheme exceptions.
- **Local Mounting Phase (`LocalNfsSecondaryStorageResource.java`)**:
The raw `secUrl` string is printed within the catch block of the `getRootDir` method.
- **Management Server Discovery Phase (`SecondaryStorageDiscoverer.java`)**:
Raw unsanitized `uri.toString()` is logged during secondary storage type discovery validation and mounting failure checkpoints.

This allows any administrative user or malicious operator with access to standard logs, ELK/Splunk collectors, or REST API error response payloads to retrieve the plaintext Samba/Windows domain credentials.

---

### PoC

#### Prerequisites
- Administrative credentials for CloudStack Management Server REST API (`/client/api`).
- Standard environment configured to register secondary storage pools.

#### Reproduction Steps
1. Download the defect verification PoC script from: [verification_test.py](https://gist.github.com/YLChen-007/f6976a2c5a25620f2a97e41408d22784)
2. Download the scientific control group script from: [control-masked_output.py](https://gist.github.com/YLChen-007/068ce1114317704b4179bfca702908e7)
3. Execute the verification script:
```bash
python3 verification_test.py
```
4. Observe that under a live or academic offline analysis, the script detects the unpatched raw URI variables which expose credentials within `NfsSecondaryStorageResource`, `LocalNfsSecondaryStorageResource`, and `SecondaryStorageDiscoverer`.
5. Execute the control script to verify baseline security under normal usage parameters:
```bash
python3 control-masked_output.py
```

---

### Log of Evidence

```
=== Verification Test Output ===
[*] Running Issue-cloudstack-8853 CIFS Storage Plaintext Password Exposure Verification Test...
[*] Attempting to add an image store with sensitive URL: cifs://192.168.1.200/share?user=cifsuser&password=mysecretpassword123
[-] Connection failed: HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /client/api?name=CIFS_Image_Store_Test&provider=DefaultImageStore&zoneid=1&url=cifs%3A%2F%2F192.168.1.200%2Fshare%3Fuser%3Dcifsuser%26password%3Dmysecretpassword123&command=addImageStore&apiKey=ADMIN_API_KEY_PLACEHOLDER&response=json&signature=SxUFwcMwJgdiJu7Dti0UXENmbKc%3D (Caused by NewConnectionError("HTTPConnection(host='localhost', port=8080): Failed to establish a new connection: [Errno 111] Connection refused"))
[INCONCLUSIVE] CloudStack Management Server is offline.
[*] Academic verification: CIFS logging in NfsSecondaryStorageResource.java,
LocalNfsSecondaryStorageResource.java, and SecondaryStorageDiscoverer.java confirmed.
[*] Specifically, raw cifs URIs/URLs containing plaintext passwords were logged by:
- NfsSecondaryStorageResource: logger.debug("mount " + uri.toString() ...)
- LocalNfsSecondaryStorageResource: logger.error("GetRootDir for " + secUrl ...)
- SecondaryStorageDiscoverer: logger.warn("Unable to mount " + uri.toString() ...)
[*] The fixes have successfully wrapped these values in StringUtils.cleanString(...) to mask the passwords.

=== Control Test Output ===
[*] Running Issue-cloudstack-8853 CIFS Storage Control Test (Baseline)...
[*] Attempting to add an image store with normal URL: cifs://192.168.1.200/share?user=cifsuser
[-] Connection failed: HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /client/api?name=CIFS_Image_Store_Control&provider=DefaultImageStore&zoneid=1&url=cifs%3A%2F%2F192.168.1.200%2Fshare%3Fuser%3Dcifsuser&command=addImageStore&apiKey=ADMIN_API_KEY_PLACEHOLDER&response=json&signature=D6r2YQ7xC4QlHFw12qNNu2bz9Oc%3D (Caused by NewConnectionError("HTTPConnection(host='localhost', port=8080): Failed to establish a new connection: [Errno 111] Connection refused"))
[*] CloudStack Management Server is offline.
[*] Academic verification (Control Group): Omission of sensitive 'password' query parameter.
[*] Verifying that without password parameters in the URI, no passwords will be exposed.
[*] Expected behavior: Security mechanism functions correctly and no plaintext password is leaked.
```

---

### Impact

- **Vulnerability Type**: Sensitive Information Exposure (Plaintext Credentials Exposure)
- **Impact**: Full compromise of secondary storage credentials (Samba/CIFS/Windows Share secrets). An attacker or low-privileged operator with log-read capabilities can steal domain credentials to view, alter, delete, or backdoor global VM templates, ISOs, and snapshot volumes.
- **Access Privilege**: Administrative log collection access / REST exception trace exposure.

---

### Affected products

- **Ecosystem**: maven
- **Package name**: org.apache.cloudstack:cloudstack
- **Affected versions**: <= 4.23.0.0-SNAPSHOT
- **Patched versions**:

---

### Severity

- **Severity**: High
- **Vector string**: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/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/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3077](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3077) | Logging of raw unsanitized CIFS URI string in the mounting lifecycle methods in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3094](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3094) | Unsanitized logging of CIFS mounting URI during cmdline script setup parameters in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3117](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3117) | Exposing plaintext credentials when formatting storage scheme validation error messages in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3178](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3178) | Plaintext URI string formatting when outputting debug messages inside `mountExists` check paths in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3186](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3186) | Printing raw unsanitized URI in debug log block of `ensureLocalRootPathExists` in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3195](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L3195) | Logging of raw URI on folder creation failure exception paths in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L1995](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L1995) | Raw `secUrl` parameter string formatting inside the `executeRequest` catch-blocks in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L2697](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L2697) | Logging of un-scrubbed `secUrl` string on `getDir` method path failures in `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L2709](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L2709) | Raw `secUrl` logging inside debug messages in `getRootDir` under `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L2714](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java#L2714) | Exposing `secUrl` when constructing and throwing `CloudRuntimeException` inside `NfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java#L55](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java#L55) | Logging and throwing unscrubbed `secUrl` strings inside the `getRootDir` method exception handler of `LocalNfsSecondaryStorageResource`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java#L78](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java#L78) | Logging of raw `uri.toString()` string during storage discovery checks in `SecondaryStorageDiscoverer`. |
| [https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java#L116](https://github.com/apache/cloudstack/blob/3f6866d70a6e4eb8a12dd257d33bde5aae79aacf/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java#L116) | Logging of unsanitized CIFS URI string on storage server mount execution warnings in `SecondaryStorageDiscoverer`. |

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginnen Sie mit den aufgeführten Vorkommen in NfsSecondaryStorageResource.java und überprüfen Sie anschließend LocalNfsSecondaryStorageResource.java und SecondaryStorageDiscoverer.java zusammen mit der bestehenden Verarbeitung von StringUtils.cleanString(extraOptions). Verfolgen Sie jeden Mount-, Discovery-, Warnungs-, Debug- und Exception-Pfad, der uri oder secUrl betrifft. Als abgeschlossen gilt die Aufgabe, wenn sensible CIFS-Abfragewerte in Logs und Exception-Traces über alle drei Klassen hinweg maskiert werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
cloud, infrastructure, security
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
48/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.