
PoC for CVE-2026-1961 — command injection in Foreman's WebSocket proxy (lib/ws_proxy.rb) via unsanitized compute resource hostname, leading to RCE as the foreman user. Responsibly disclosed and patched.
Proof-of-concept for a command injection vulnerability in Foreman's WebSocket proxy (lib/ws_proxy.rb), disclosed responsibly to Red Hat and patched.
Foreman's WebSocket proxy interpolates an unsanitized host value — sourced from a compute resource provider's API response (e.g. VMware vSphere HostSystem.name) — directly into a shell command executed via Open3.popen3. An attacker who controls or spoofs a compute resource server that a Foreman instance connects to can inject arbitrary shell commands, achieving remote code execution as the foreman user when an administrator opens a VM's Console.
Successful exploitation grants access to Foreman's database credentials and encryption keys, exposing all stored infrastructure credentials (vCenter, AWS, SSH keys, API tokens) and enabling further pivoting into the managed infrastructure.
| CVE | CVE-2026-1961 |
| CWE | CWE-78 (OS Command Injection) |
| CVSS 3.1 | 8.0 (High) — AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H |
| Affected component | lib/ws_proxy.rb |
| Affected versions | Foreman up to and including 3.18.0 (confirmed on 3.17.0; code path unchanged since 2020) |
| Fixed in | Foreman 3.18.1, 3.17.2, 3.16.3 |
| Authentication required | None (attacker runs the malicious server; the Foreman admin authenticates to it as part of normal workflow) |
| User interaction | Administrator clicks Console on a VM (normal workflow) |
| Advisory | https://access.redhat.com/security/cve/cve-2026-1961 |
At lib/ws_proxy.rb:44, the host parameter is interpolated directly into a shell command string:
cmd = "websockify --daemon --idle-timeout=#{idle_timeout} --timeout=#{timeout} #{port} #{host}:#{host_port}"
host comes from the compute resource API response and is never sanitized before being passed to a shell via Open3.popen3.
malicious_vsphere_server.py implements a minimal vSphere SOAP API — enough to handle authentication and VM enumeration — and returns a poisoned HostSystem.name value containing a shell metacharacter payload.
python3 malicious_vsphere_server.py
python3 malicious_vsphere_server.py
VMware<attacker_ip>user / pass)EvilDatacenter)VNCTestVMfind /tmp -name "vsphere_rce.txt" 2>/dev/null
cat /tmp/systemd-private-*/tmp/vsphere_rce.txt
foremanHoussam Sahli (Malleum)
Released post-patch, following coordinated disclosure. Provided for authorized security testing and educational purposes only. Do not use against systems you do not own or do not have explicit permission to test.