fix: backport ws token fix

isekai-main
Barış Soner Uşaklı 2 years ago
parent a5d92da9dd
commit 62e162cf1e

@ -15,6 +15,9 @@ app = window.app || {};
reconnectionDelay: config.reconnectionDelay, reconnectionDelay: config.reconnectionDelay,
transports: config.socketioTransports, transports: config.socketioTransports,
path: config.relative_path + '/socket.io', path: config.relative_path + '/socket.io',
query: {
_csrf: config.csrf_token,
},
}; };
window.socket = io(config.websocketAddress, ioParams); window.socket = io(config.websocketAddress, ioParams);

@ -5,11 +5,22 @@ const { csrfSync } = require('csrf-sync');
const { const {
generateToken, generateToken,
csrfSynchronisedProtection, csrfSynchronisedProtection,
isRequestValid,
} = csrfSync({ } = csrfSync({
size: 64 getTokenFromRequest: (req) => {
if (req.headers['x-csrf-token']) {
return req.headers['x-csrf-token'];
} else if (req.body && req.body.csrf_token) {
return req.body.csrf_token;
} else if (req.query) {
return req.query._csrf;
}
},
size: 64,
}); });
module.exports = { module.exports = {
generateToken, generateToken,
csrfSynchronisedProtection, csrfSynchronisedProtection,
isRequestValid,
}; };

@ -2,11 +2,11 @@
const async = require('async'); const async = require('async');
const path = require('path'); const path = require('path');
const { csrfSynchronisedProtection } = require('./csrf');
const validator = require('validator'); const validator = require('validator');
const nconf = require('nconf'); const nconf = require('nconf');
const toobusy = require('toobusy-js'); const toobusy = require('toobusy-js');
const util = require('util'); const util = require('util');
const { csrfSynchronisedProtection } = require('./csrf');
const plugins = require('../plugins'); const plugins = require('../plugins');
const meta = require('../meta'); const meta = require('../meta');

@ -34,13 +34,25 @@ Sockets.init = async function (server) {
} }
} }
io.use(authorize);
io.on('connection', onConnection); io.on('connection', onConnection);
const opts = { const opts = {
transports: nconf.get('socket.io:transports') || ['polling', 'websocket'], transports: nconf.get('socket.io:transports') || ['polling', 'websocket'],
cookie: false, cookie: false,
allowRequest: (req, callback) => {
authorize(req, (err) => {
if (err) {
return callback(err);
}
const csrf = require('../middleware/csrf');
const isValid = csrf.isRequestValid({
session: req.session || {},
query: req._query,
headers: req.headers,
});
callback(null, isValid);
});
},
}; };
/* /*
* Restrict socket.io listener to cookie domain. If none is set, infer based on url. * Restrict socket.io listener to cookie domain. If none is set, infer based on url.
@ -62,7 +74,11 @@ Sockets.init = async function (server) {
}; };
function onConnection(socket) { function onConnection(socket) {
socket.ip = (socket.request.headers['x-forwarded-for'] || socket.request.connection.remoteAddress || '').split(',')[0]; socket.uid = socket.request.uid;
socket.ip = (
socket.request.headers['x-forwarded-for'] ||
socket.request.connection.remoteAddress || ''
).split(',')[0];
socket.request.ip = socket.ip; socket.request.ip = socket.ip;
logger.io_one(socket, socket.uid); logger.io_one(socket, socket.uid);
@ -231,9 +247,7 @@ async function validateSession(socket, errorMsg) {
const cookieParserAsync = util.promisify((req, callback) => cookieParser(req, {}, err => callback(err))); const cookieParserAsync = util.promisify((req, callback) => cookieParser(req, {}, err => callback(err)));
async function authorize(socket, callback) { async function authorize(request, callback) {
const { request } = socket;
if (!request) { if (!request) {
return callback(new Error('[[error:not-authorized]]')); return callback(new Error('[[error:not-authorized]]'));
} }
@ -246,15 +260,13 @@ async function authorize(socket, callback) {
}); });
const sessionData = await getSessionAsync(sessionId); const sessionData = await getSessionAsync(sessionId);
request.session = sessionData;
let uid = 0;
if (sessionData && sessionData.passport && sessionData.passport.user) { if (sessionData && sessionData.passport && sessionData.passport.user) {
request.session = sessionData; uid = parseInt(sessionData.passport.user, 10);
socket.uid = parseInt(sessionData.passport.user, 10);
} else {
socket.uid = 0;
} }
request.uid = socket.uid; request.uid = uid;
callback(); callback(null, uid);
} }
Sockets.in = function (room) { Sockets.in = function (room) {

@ -95,7 +95,7 @@ helpers.logoutUser = function (jar, callback) {
}); });
}; };
helpers.connectSocketIO = function (res, callback) { helpers.connectSocketIO = function (res, csrf_token, callback) {
const io = require('socket.io-client'); const io = require('socket.io-client');
let cookies = res.headers['set-cookie']; let cookies = res.headers['set-cookie'];
cookies = cookies.filter(c => /express.sid=[^;]+;/.test(c)); cookies = cookies.filter(c => /express.sid=[^;]+;/.test(c));
@ -106,6 +106,9 @@ helpers.connectSocketIO = function (res, callback) {
Origin: nconf.get('url'), Origin: nconf.get('url'),
Cookie: cookie, Cookie: cookie,
}, },
query: {
_csrf: csrf_token,
},
}); });
socket.on('connect', () => { socket.on('connect', () => {

@ -73,7 +73,7 @@ describe('socket.io', () => {
}, (err, res) => { }, (err, res) => {
assert.ifError(err); assert.ifError(err);
helpers.connectSocketIO(res, (err, _io) => { helpers.connectSocketIO(res, body.csrf_token, (err, _io) => {
io = _io; io = _io;
assert.ifError(err); assert.ifError(err);

Loading…
Cancel
Save