[socket.io] Cross-Site Websockets Hijacking
The socket.io module was vulnerable to cross-site websocker hijacking attack due to the incorrect parsing of the http Origin header. The vulnerability was found in 2.3.0 version.
Socket.IO enables real-time bidirectional event-based communication
Links
Proof of concept:
app.js:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
io.origins(['http://localhost:80']); //we believe that this module will decline other origins
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
});
http.listen(80, () => {
console.log('listening on *:80');
});
index.html:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
Initial connection:
HTTP/1.1 101 Switching Protocols means that the connection was successful.
- Try to change origin to
something.io
.HTTP/1.1 400 Bad Request
is returned and it is good, because we allowed only localhost origin in app.js.
- Change origin to localhost`something.io
As we can see - the module thinks that the origin is localhost while Safari thinks that it is a subdomain of something.io. Moreover, Safari isn’t the only affected browser. This works in latest Firefox as well. Just replace ` with $.
Impact
After the successful connection from the attacker’s domain, the attacker can receive and send websocket messages on behalf of a user.