const express = require('express'); const https = require('https'); const fs = require('fs'); const { Server } = require('socket.io'); const path = require('path'); const app = express(); const HOST = '10.0.0.51'; const PORT = 443; // Guardrail: Max allowed size for signaling metadata payloads (64KB) const MAX_SIGNAL_PAYLOAD_SIZE = 64 * 1024; function startServer() { let privateKey, certificate; try { privateKey = fs.readFileSync(path.join(__dirname, 'key.pem'), 'utf8'); certificate = fs.readFileSync(path.join(__dirname, 'cert.pem'), 'utf8'); } catch (err) { console.error('Failed to load local certificates. Ensure key.pem and cert.pem exist.', err); process.exit(1); } const server = https.createServer({ key: privateKey, cert: certificate }, app); // Guardrail: Enforce max HTTP/WebSocket buffer size on Socket.io (1MB limit for signaling) const io = new Server(server, { maxHttpBufferSize: 1e6 }); app.use(express.static(path.join(__dirname, 'public'))); io.on('connection', (socket) => { socket.on('join-room', (roomId) => { if (typeof roomId !== 'string' || roomId.length > 128) return; socket.join(roomId); socket.roomId = roomId; socket.to(roomId).emit('user-joined', socket.id); }); // Signaling guardrails: Validate payload sizes before broadcasting socket.on('offer', ({ target, offer }) => { if (JSON.stringify(offer).length > MAX_SIGNAL_PAYLOAD_SIZE) return; io.to(target).emit('offer', { sender: socket.id, offer }); }); socket.on('answer', ({ target, answer }) => { if (JSON.stringify(answer).length > MAX_SIGNAL_PAYLOAD_SIZE) return; io.to(target).emit('answer', { sender: socket.id, answer }); }); socket.on('ice-candidate', ({ target, candidate }) => { if (candidate && JSON.stringify(candidate).length > MAX_SIGNAL_PAYLOAD_SIZE) return; io.to(target).emit('ice-candidate', { sender: socket.id, candidate }); }); socket.on('disconnect', () => { if (socket.roomId) { socket.to(socket.roomId).emit('user-disconnected', socket.id); } }); }); server.listen(PORT, HOST, () => { console.log(`CrabChat signaling server running securely at https://${HOST}:${PORT}`); }); } startServer();