Untrusted URL Parameters Allow Arbitrary WebSocket Connections (Follow-up to #2011)
Describe the bug
Dear noVNC maintainers
I was conducting a penetration test for a client and have identified a potential issue in the latest version of noVNC (previously reported here: https://github.com/novnc/noVNC/issues/2011). From my point of view, issue https://github.com/novnc/noVNC/issues/2011 was raised correctly, but I believe the impact described by 0xspade may not fully capture the risk, which could have led to it being closed.
As 0xspade outlines, an attacker can control the host and port the victim connects to. However, the issue is not limited to IP disclosure. By allowing untrusted, user-controlled connection parameters via URL, an attacker can cause a victim's browser to establish a WebSocket connection to an attacker-controlled VNC server while rendering the session under the trusted origin.
I understand that this is the intended usage, but without safeguards this behaviour can be abused for phishing attacks, such as presenting a login interface to capture user credentials. This is particularly relevant in scenarios where the victim expects to connect to a legitimate remote access portal, such as in the penetration test I was performing.
To reproduce
Below are two example URLs that an attacker could deliver to a victim (e.g., link via email; Cross-Site Request Forgery), while hosting a malicious VNC server that mimicks the target host the attacker wants to phish credentials for:
- vnc.html:
https://<host>:<port>/vnc.html#host=<adversaryhost>&port=<adversaryport>&autoconnect=true&encrypt=1 - vnc_lite.html:
https://<host>:<port>/vnc_lite.html?host=<adversaryhost>&port=<adversaryport>&password=
Expected behavior From my point of view, 0xspade correctly recommended an appropriate mitigation: implementing host whitelisting. Even in a "serverless" context (as outlined in the ticket linked above), this approach should be feasible and would prevent the attack scenario described above. Specifically, the host value supplied via the parameter should be validated against a predefined set of hosts sourced from a list located at a trusted location the attacker does not control (e.g., file system, web root). If the value matches an approved entry, the connection is allowed to proceed; otherwise, it is rejected, effectively blocking the attack.
Alternatively, the issue could be mitigated through a properly configured Content Security Policy (CSP) that restricts permitted WebSocket endpoints (ws: / wss:). However, in practice, many system administrators may not be familiar with configuring CSP correctly. Providing clear guidance (e.g., hardening instruction) would therefore be important to ensure this mitigation is applied effectively.
If you are not keen to implement this suggestion as a core mechanism, maybe you could consider to introduce it as optional, allowing clients to configure trusted destinations when they want to harden their noVNC deployment.
Screenshots I will re-create the customer's circumstances in my laboratory per request, as I can not use screenshots from the original engagement. https://github.com/novnc/noVNC/issues/2011 already features some screenshots.
Client (please complete the following information):
- OS: All
- Browser: All
- Browser version: All
Server (please complete the following information):
- noVNC version: Latest and before
- VNC server: All
- WebSocket proxy: confirmed with websockify
Additional context N/A.
Source: novnc/noVNC