Security Bug: Unauthenticated Socket.io Connections Can Join Any Workout Room
Description
The Socket.io server accepts connections and room join events without verifying
a Firebase Auth token. Any unauthenticated client (or a different authenticated
user) who knows a room name (or guesses it) can join an active workout session
and receive real-time pose landmark coordinates, rep counts, and form scores
being broadcast for another user's workout.
Steps to Reproduce
- Start a workout session as User A and note the Socket.io room name
(visible in the network inspector or browser console).
- Open a new browser tab and connect to the Socket.io server without logging in:
const socket = io("http://localhost:3001");
socket.emit("join-room", "<room-name>");
socket.on("pose-data", (data) => console.log("Intercepted:", data));
- Observe User A's real-time pose data arrives in User B's console.
Root Cause
The Socket.io connection handler does not call a token validation middleware.
Room join events are processed without any ownership check.
Impact
Biometric data (body pose, exercise form, rep timing) is broadcast to any
connected client, violating user privacy and potentially enabling exercise
session surveillance.
Proposed Fix
Add Firebase token verification to the Socket.io connection middleware:
const admin = require("firebase-admin");
io.use(async (socket, next) => {
const token = socket.handshake.auth?.token;
if (!token) return next(new Error("Authentication required"));
try {
const decoded = await admin.auth().verifyIdToken(token);
socket.userId = decoded.uid;
next();
} catch {
next(new Error("Invalid token"));
}
});
io.on("connection", (socket) => {
socket.on("join-room", (roomId) => {
// Verify socket.userId owns or is invited to roomId before joining
if (!isAuthorised(socket.userId, roomId)) return;
socket.join(roomId);
});
});
Security Bug: Unauthenticated Socket.io Connections Can Join Any Workout Room
Description
The Socket.io server accepts connections and room join events without verifying
a Firebase Auth token. Any unauthenticated client (or a different authenticated
user) who knows a room name (or guesses it) can join an active workout session
and receive real-time pose landmark coordinates, rep counts, and form scores
being broadcast for another user's workout.
Steps to Reproduce
(visible in the network inspector or browser console).
Root Cause
The Socket.io connection handler does not call a token validation middleware.
Room join events are processed without any ownership check.
Impact
Biometric data (body pose, exercise form, rep timing) is broadcast to any
connected client, violating user privacy and potentially enabling exercise
session surveillance.
Proposed Fix
Add Firebase token verification to the Socket.io connection middleware: