Bug 2469260 (CVE-2026-92747) - CVE-2026-92747 cockpit-machines: cockpit-machines: Sensitive Data Exposure of guest credentials via JSON argument in process list
Summary: CVE-2026-92747 cockpit-machines: cockpit-machines: Sensitive Data Exposure of...
Keywords:
Status: NEW
Alias: CVE-2026-92747
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 2537075
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-05-11 20:00 UTC by OSIDB Bzimport
Modified: 2026-09-18 19:20 UTC (History)
3 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-05-11 20:00:41 UTC
AI_ONLY_REPORT
package: cockpit-machines-348-1.el10
------
Summary: Sensitive Data Exposure in Process List via JSON Argument in  
install_machine.py: VM installation credentials are passed in a JSON  
command-line argument, which can expose `rootPassword` and `userPassword`  
through local process inspection on affected host configurations.
Requirements to exploit: Local access to the host running  
`cockpit-machines`, the ability to inspect another running process's  
command line, and a VM create/install operation that supplies  
`rootPassword` and/or `userPassword` while `install_machine.py` is still  
running. Exploitability depends on host process-visibility settings and  
timing.
Component affected: `cockpit-machines` create/install flow in  
`src/libvirtApi/domain.ts` (`domainCreate`, `domainInstall`) and  
`src/scripts/install_machine.py`
Version affected: `cockpit-machines-348-1.el10`
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not notified.
CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:N/A:N - 4.7 (MEDIUM)
AV:L - The issue is exploitable from the local host by inspecting  
process arguments.
AC:L - Once the affected process is running, reading `ps` output or  
`/proc/<pid>/cmdline` is straightforward where host policy permits it.
PR:L - The attacker needs local access sufficient to observe the process  
on the host.
UI:R - Credential exposure occurs only when a user triggers the affected  
VM create/install flow with password fields populated.
S:U - The issue does not cross a security boundary within the product.
C:H - The exposed data can include guest login credentials, including  
`rootPassword` and `userPassword`, or other directly reusable credential  
material in some paths.
I:N - This issue does not directly modify data.
A:N - This issue does not directly affect service availability.
Impact: Moderate. This is a confidentiality issue that can disclose guest  
credentials, but it requires local host access, depends on  
process-visibility policy, and is only exposed while the affected  
create/install workflow is active. That is consistent with a flaw that can  
lead to compromise under specific circumstances, but is not an easy remote  
or unauthenticated system-compromise condition.
Embargo: no
Reason: The issue appears to require local access and runtime timing,  
with mitigation available through a relatively contained code change and  
host process-visibility hardening. This is better handled through normal  
coordinated remediation than embargoed treatment.
Acknowledgement: Aisle Research
Vulnerability Details: The VM create/install path passes a full JSON  
payload to `install_machine.py` through `argv`, and that payload includes  
credential fields. The Python side then deserializes the JSON directly from  
the first positional argument:
```python
args = json.loads(sys.argv[1], strict=False)
```
The affected create and install flows build JSON that includes  
`rootPassword` and `userPassword`, then invoke `install_machine.py` with  
that JSON as a command-line argument. This makes the credentials observable  
through process metadata on hosts where other local users can inspect  
command lines. The exposure window can be meaningful because the install  
path may remain active for an extended period during guest installation.
Steps to reproduce:
1. Start a VM creation or installation through the affected workflow with  
`rootPassword` and/or `userPassword` set.
2. While `install_machine.py` is still running, identify the process on the  
same host:
`ps -ef | grep install_machine.py`
3. Read the command line for the matching process:
`tr '\0' ' ' < /proc/<pid>/cmdline`
4. Observe that the JSON argument contains `rootPassword` and/or  
`userPassword` in cleartext, or other directly reusable credential material  
in some cloud-image paths.
If host policy restricts cross-process inspection, the disclosure may not  
be observable from a separate local account, but the underlying behavior  
still places secrets in `argv`.
Mitigation: Avoid passing secrets in process arguments. Until code is  
corrected, reduce exposure by restricting process inspection on the host  
where possible and by avoiding use of password-bearing install flows when  
another provisioning method is available. Hardening `/proc` visibility can  
reduce exploitability, but it does not remove the underlying  
secret-in-`argv` issue.
Proposed Fix: Read the JSON payload from standard input, keep an `argv`  
fallback only for compatibility, and update both call sites to write the  
payload via `Spawn.input()` instead of passing it in the command line.
```diff
diff --git a/src/scripts/install_machine.py b/src/scripts/install_machine.py
index 0000000..1111111 100755
— a/src/scripts/install_machine.py
+++ b/src/scripts/install_machine.py
@@ -313,9 +313,16 @@ def inject_metadata(xml):
logging.basicConfig(level=logging.ERROR, format='%(message)s')
-logging.debug(sys.argv[1])
-
-args = json.loads(sys.argv[1], strict=False)
+payload = None
+if len(sys.argv) > 1 and sys.argv[1]:
+    # backward compatibility: prefer stdin, accept argv for older callers
+    payload = sys.argv[1]
+else:
+    payload = sys.stdin.read()
+
+if not payload:
+    raise ValueError("missing install_machine payload")
+
+args = json.loads(payload, strict=False)
logging.debug(args)
diff --git a/src/libvirtApi/domain.ts b/src/libvirtApi/domain.ts
index 2222222..3333333 100644
— a/src/libvirtApi/domain.ts
+++ b/src/libvirtApi/domain.ts
@@ -591,12 +591,13 @@ export async function domainCreate(...) {
await hashPasswords(args);
       await python.spawn(
+        const p = python.spawn(
              installVmScript,

           [JSON.stringify(args)],
+            [],
              {
                  err: "message",
                  environ: ['LC_ALL=C.UTF-8'],
                  ...(connectionName === "system" ? { superuser: "try" } : {  
})
              });
+        p.input(JSON.stringify(args));
+        await p;
@@ -1022,13 +1023,14 @@ export async function domainInstall({ vm } : { vm:  
VM }): Promise<string> {

   return python.spawn(
+    const p = python.spawn(
          installVmScript,

       [args],
+        [],
          {
              err: "message",
              environ: ['LC_ALL=C.UTF-8'],
              ...(vm.connectionName === "system" ? { superuser: "try" } : {  
})

       })

           .catch(ex => {
+        });
+    p.input(args);
+    return p.catch(ex => {
                  console.error(JSON.stringify(ex));
                  return Promise.reject(ex);
              })
```


------
This report was generated using AI technology. Always review AI-generated  
content prior to use


Note You need to log in before you can comment on or make changes to this bug.