Title: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access · Issue #13302 · apache/cloudstack · GitHub
Open Graph Title: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access · Issue #13302 · apache/cloudstack
X Title: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access · Issue #13302 · apache/cloudstack
Description: Advisory Details Title: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access Description: An incomplete security audit fix in Apache CloudStack's KVM hypervisor agent causes VM graphics/VNC console passwords to...
Open Graph Description: Advisory Details Title: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access Description: An incomplete security audit fix in Apache CloudStack's KVM hypervisor agent cau...
X Description: Advisory Details Title: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access Description: An incomplete security audit fix in Apache CloudStack's KVM hypervisor agent...
Opengraph URL: https://github.com/apache/cloudstack/issues/13302
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access","articleBody":"### Advisory Details\n\n**Title**: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access\n\n**Description**:\n\nAn incomplete security audit fix in Apache CloudStack's KVM hypervisor agent causes VM graphics/VNC console passwords to be permanently stripped when VM snapshots are created or redefined. Reverting a VM to these snapshots restores the VM using the password-less XML configuration, allowing unauthorized network-adjacent attackers to connect to the VM's guest OS console without VNC authentication.\n\n### Summary\n\nAn incomplete fix for **CVE-2015-3252** (specifically, missing the VM snapshot definition/restoration path) allows attackers to bypass VNC authentication controls on KVM-managed guest virtual machines. When a KVM hypervisor agent restores VM snapshot metadata, it calls `dm.getXMLDesc(0)`, which strips the graphics tag's password property (`passwd='...'`). Subsequent reversion to this snapshot re-registers the VM with libvirt without a VNC password, leaving the virtual machine console wide open to unauthenticated users.\n\n### Details\n\nDuring patch completeness audits of Apache CloudStack, we analyzed the patch commit `5d29b63cfa98a15d7734798c5b29a43658d7f112` for **CVE-2015-3252**. The original issue stripped VNC passwords because the domain XML was retrieved using `dm.getXMLDesc(0)` (the default flag `0` explicitly removes all security-sensitive credentials).\n\nWhile the developers successfully fixed the VM reboot and VM migration paths by using `dm.getXMLDesc(1)` and `dm.getXMLDesc(8)` respectively, they **missed the snapshot definition and restoration path** in `LibvirtRestoreVMSnapshotCommandWrapper.java`.\n\nInside `LibvirtRestoreVMSnapshotCommandWrapper.java`:\n```java\nDomain dm = null;\ntry {\n final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();\n Connect conn = libvirtUtilitiesHelper.getConnection();\n dm = libvirtComputingResource.getDomain(conn, vmName);\n\n if (dm == null) {\n return new RestoreVMSnapshotAnswer(cmd, false,\n \"Restore Instance Snapshot Failed due to can not find Instance: \" + vmName);\n }\n String xmlDesc = dm.getXMLDesc(0); // \u003c--- 💥 Insecure Flag 0 strips VNC passwd!\n```\n\nThis insecure XML description is then used to generate the snapshot metadata via `libvirtUtilitiesHelper.generateVMSnapshotXML(...)` and persisted on the host with `dm.snapshotCreateXML(vmSnapshotXML, flags)`.\nBecause `getXMLDesc(0)` was called, the `\u003cgraphics type='vnc' ...\u003e` tag has no `passwd` attribute inside the stored snapshot. When a tenant user later reverts the VM to this snapshot, libvirt restores the graphics configuration from this stripped definition, permanently erasing VNC password protection and exposing the VNC port (ports `5900+`) to unauthenticated console connections.\n\n### PoC\n\n#### Prerequisites\n\n- Apache CloudStack KVM Agent installed on a KVM hypervisor.\n- A virtual machine configured with VNC password protection.\n- Docker \u0026 Python 3 installed locally.\n\n#### Reproduction Steps\n\n1. Set up the local test simulation by downloading the Docker Compose file: [docker-compose.yml](https://gist.github.com/YLChen-007/3b65889cb69a220624ccc84ed7157681)\n\n2. Start the simulation environment:\n ```bash\n docker compose up -d\n ```\n\n3. Download the automated static codebase audit script: [verification_test.py](https://gist.github.com/YLChen-007/d08d29a49aed92d1b8c7c73d7883321a)\n\n4. Execute the verification script:\n ```bash\n python3 verification_test.py\n ```\n\n5. Download the control group verification script: [control-secure_xml_flag.py](https://gist.github.com/YLChen-007/45d77061579e39f233761f32d1ac10bf)\n\n6. Execute the control group script:\n ```bash\n python3 control-secure_xml_flag.py\n ```\n\n### Log of Evidence\n\n```\n==========================================================================\nCVE-2015-3252 VM Snapshot VNC Password Loss Variant Verification Test\n==========================================================================\n[*] Vulnerable Source File Path: /root/distributed-project/cloudstack/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreVMSnapshotCommandWrapper.java\n[*] CloudStack Management Server API URL: http://localhost:8080/client/api\n[*] Attempting to connect to live CloudStack Management Server...\n[-] Live CloudStack Management Server is not reachable at localhost:8080.\n[*] Falling back to static/bytecode audit verification on the compiled/source environment...\n\n--- Static Source Audit Flow ---\n[*] Analyzing source code file for unpatched CVE-2015-3252 variant pattern...\n[+] Match found! Found vulnerable pattern 'dm.getXMLDesc(0)' in source file.\n Line 59: String xmlDesc = dm.getXMLDesc(0);\n\n==========================================================================\n[DEFECT CONFIRMED] - The VNC password loss variant in LibvirtRestoreVMSnapshotCommandWrapper is present!\nExplanation: The Domain XML is fetched using dm.getXMLDesc(0) which strips the sensitive VNC password.\nRedefining the snapshot with this XML will cause permanent loss of the password upon snapshot revert.\n==========================================================================\n\n==========================================================================\nCVE-2015-3252 VM Snapshot VNC Password Loss Variant - Control Group Test\n==========================================================================\n[*] Control Source File Path: /root/distributed-project/cloudstack/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java\n\n--- Control Group Static Source Audit Flow ---\n[*] Analyzing control source code file for correct security mechanism usage (flag 1)...\n[+] Match found! Found secure pattern 'getXMLDesc(1)' in control source file.\n Line 89: parser.parseDomainXML(domain.getXMLDesc(1));\n\n==========================================================================\n[CONTROL SUCCESSFUL] - The security mechanism (VIR_DOMAIN_XML_SECURE flag 1)\nis correctly functioning and implemented in standard control components.\nThis confirms that the secure behavior is fully supported and expected by design,\nmaking the 'getXMLDesc(0)' pattern in the snapshot flow a genuine security defect.\n==========================================================================\n```\n\n### Impact\n\n- **Vulnerability Category**: Cryptographic credential loss / Unauthenticated Access / Information Disclosure (CWE-200 / CWE-250)\n- **Compromised Assets**: Entire Guest Virtual Machine OS.\n- **Security Impact**: High. Any network-adjacent attacker or unauthorized console proxy user can fully hijack the guest OS console via the hypervisor's unprotected VNC port (usually `5900+`) without needing credentials, bypassing all VM-level console authentication mechanisms.\n\n### Affected products\n\n- **Ecosystem**: maven\n- **Package name**: org.apache.cloudstack:cloudstack-plugins-hypervisor-kvm\n- **Affected versions**: \u003c= 4.22.1.0\n- **Patched versions**: \u003cNone\u003e\n\n### Severity\n\n- **Severity**: High\n- **Vector string**: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H\n\n### Weaknesses\n\n- **CWE**: CWE-200: Exposure of Sensitive Information to an Unauthorized Actor\n\n### Occurrences\n\n| Permalink | Description |\n| :--- | :--- |\n| [https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreVMSnapshotCommandWrapper.java#L59](https://github.com/apache/cloudstack/blob/348ce953a99246a756b527994f7745a7be038234/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreVMSnapshotCommandWrapper.java#L59) | The vulnerable `execute` method retrieves domain XML with a flag value of `0` in `LibvirtRestoreVMSnapshotCommandWrapper.java`, stripping the graphics/VNC password. |","author":{"url":"https://github.com/YLChen-007","@type":"Person","name":"YLChen-007"},"datePublished":"2026-06-01T07:04:54.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/13302/cloudstack/issues/13302"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:8be96fc1-a03d-7835-b432-5caab66f8244 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | AEAC:A2022:3FD76C:5A2B40:6A4E6DF1 |
| html-safe-nonce | 15cf0709aa3c71b71321291db8e55f47347a8ef936852ab77b31e4492abd4d86 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBRUFDOkEyMDIyOjNGRDc2Qzo1QTJCNDA6NkE0RTZERjEiLCJ2aXNpdG9yX2lkIjoiMTI2MzQ5OTk5NjM4NjE5Mjg4MSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | dae767144a7d82fa42b1292facc823b8de9bfaa5cadf3817fd9a0e4cd55e3932 |
| hovercard-subject-tag | issue:4561052622 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/apache/cloudstack/13302/issue_layout |
| twitter:image | https://opengraph.githubassets.com/d435a6fe12408540f9afde50a10bf5a8595b1ddfb4970f02f0537c60c75254a5/apache/cloudstack/issues/13302 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/d435a6fe12408540f9afde50a10bf5a8595b1ddfb4970f02f0537c60c75254a5/apache/cloudstack/issues/13302 |
| og:image:alt | Advisory Details Title: VM Snapshot VNC Password Loss Variant leading to Unauthenticated Console Access Description: An incomplete security audit fix in Apache CloudStack's KVM hypervisor agent cau... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | YLChen-007 |
| hostname | github.com |
| expected-hostname | github.com |
| None | 41b6ab3ba6d20a71766ac245b5a4a94c6fc672a9cd4da7d44c1b33ab8bf6a21c |
| turbo-cache-control | no-preview |
| go-import | github.com/apache/cloudstack git https://github.com/apache/cloudstack.git |
| octolytics-dimension-user_id | 47359 |
| octolytics-dimension-user_login | apache |
| octolytics-dimension-repository_id | 9759448 |
| octolytics-dimension-repository_nwo | apache/cloudstack |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 9759448 |
| octolytics-dimension-repository_network_root_nwo | apache/cloudstack |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | e6a744804e8e70f97b4d5a18a94dcc63db22f97a |
| ui-target | canary-2 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width