From 6cf2c40240c0345b8742283f5177e21645c48ad2 Mon Sep 17 00:00:00 2001 From: calzoneman Date: Sun, 1 Dec 2013 17:10:37 -0600 Subject: [PATCH] add extra user input validation and truncation --- lib/api.js | 125 +++++++++++++++++++++++++++++++++++++++++++++++-- lib/channel.js | 56 ++++++++++------------ lib/user.js | 2 +- 3 files changed, 148 insertions(+), 35 deletions(-) diff --git a/lib/api.js b/lib/api.js index cf7fe407..3a20b7b2 100644 --- a/lib/api.js +++ b/lib/api.js @@ -183,9 +183,9 @@ module.exports = function (Server) { app.post("/api/login", function (req, res) { res.type("application/jsonp"); res.setHeader("Access-Control-Allow-Origin", "*"); - var name = req.body.name; - var pw = req.body.pw; - var session = req.body.session; + var name = req.body.name || ""; + var pw = req.body.pw || ""; + var session = req.body.session || ""; // for some reason CyTube previously allowed guest logins // over the API...wat @@ -226,6 +226,15 @@ module.exports = function (Server) { res.setHeader("Access-Control-Allow-Origin", "*"); var name = req.body.name; var pw = req.body.pw; + if (typeof name !== "string" || + typeof pw !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } var ip = getIP(req); // Limit registrations per IP within a certain time period @@ -300,6 +309,17 @@ module.exports = function (Server) { var oldpw = req.body.oldpw; var newpw = req.body.newpw; + if (typeof name !== "string" || + typeof oldpw !== "string" || + typeof newpw !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + if(!oldpw || !newpw) { res.jsonp({ success: false, @@ -340,6 +360,15 @@ module.exports = function (Server) { res.setHeader("Access-Control-Allow-Origin", "*"); var name = req.body.name; var email = req.body.email; + if (typeof name !== "string" || + typeof email !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } var ip = getIP(req); var hash = false; @@ -407,6 +436,14 @@ module.exports = function (Server) { app.get("/api/account/passwordrecover", function (req, res) { res.type("application/jsonp"); var hash = req.query.hash; + if (typeof hash !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } var ip = getIP(req); db.recoverUserPassword(hash, function (err, auth) { @@ -457,6 +494,25 @@ module.exports = function (Server) { var session = req.body.session; var img = req.body.profile_image; var text = req.body.profile_text; + if (typeof name !== "string" || + typeof session !== "string" || + typeof img !== "string" || + typeof text !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + + if (img.length > 255) { + img = img.substring(0, 255); + } + + if (text.length > 255) { + text = text.substring(0, 255); + } db.userLoginSession(name, session, function (err, row) { if(err) { @@ -507,6 +563,18 @@ module.exports = function (Server) { var pw = req.body.pw; var email = req.body.email; + if (typeof name !== "string" || + typeof pw !== "string" || + typeof email !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + + if(!email.match(/^[\w_\.]+@[\w_\.]+[a-z]+$/i)) { res.jsonp({ success: false, @@ -555,6 +623,16 @@ module.exports = function (Server) { var name = req.query.name; var session = req.query.session; + if (typeof name !== "string" || + typeof session !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + db.userLoginSession(name, session, function (err, row) { if(err) { res.jsonp({ @@ -593,6 +671,17 @@ module.exports = function (Server) { var session = req.query.session; var types = req.query.actions; + if (typeof name !== "string" || + typeof session !== "string" || + typeof types !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + db.userLoginSession(name, session, function (err, row) { if(err) { if(err !== "Invalid session" && @@ -644,6 +733,16 @@ module.exports = function (Server) { var name = req.query.name; var session = req.query.session; + if (typeof name !== "string" || + typeof session !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + db.userLoginSession(name, session, function (err, row) { if(err) { if(err !== "Invalid session" && @@ -671,6 +770,16 @@ module.exports = function (Server) { var name = req.query.name; var session = req.query.session; + if (typeof name !== "string" || + typeof session !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + db.userLoginSession(name, session, function (err, row) { if(err) { if(err !== "Invalid session" && @@ -698,6 +807,16 @@ module.exports = function (Server) { var name = req.query.name; var session = req.query.session; + if (typeof name !== "string" || + typeof session !== "string") { + res.status(400); + res.jsonp({ + success: false, + error: "Invalid request" + }); + return; + } + db.userLoginSession(name, session, function (err, row) { if(err) { if(err !== "Invalid session" && diff --git a/lib/channel.js b/lib/channel.js index 1c7001ba..a03e07d0 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -826,6 +826,9 @@ Channel.prototype.handlePendingJoins = function () { }; Channel.prototype.userJoin = function(user, password) { + if (password.length > 100) { + password = password.substring(0, 100); + } var self = this; if (!self.ready) { self.addPendingJoin(user, password); @@ -1869,12 +1872,13 @@ Channel.prototype.tryUpdate = function(user, data) { return; } - if(this.playlist.current.media.id != data.id) { + if (this.playlist.current.media.id !== data.id || + isNaN(+data.currentTime)) { return; } - this.playlist.current.media.currentTime = data.currentTime; - this.playlist.current.media.paused = data.paused; + this.playlist.current.media.currentTime = +data.currentTime; + this.playlist.current.media.paused = Boolean(data.paused); this.sendAll("mediaUpdate", this.playlist.current.media.timeupdate()); } @@ -2013,10 +2017,7 @@ Channel.prototype.trySetLock = function(user, data) { return; } - if(data.locked == undefined) { - return; - } - + data.locked = Boolean(data.locked); this.logger.log("*** " + user.name + " set playlist lock to " + data.locked); this.setLock(data.locked); } @@ -2036,6 +2037,11 @@ Channel.prototype.tryRemoveFilter = function(user, f) { return; } + // Don't care about the other parameters since we're just removing + if (typeof f.name !== "string") { + return; + } + this.logger.log("%%% " + user.name + " removed filter: " + f.name); this.removeFilter(f); } @@ -2079,6 +2085,14 @@ Channel.prototype.tryUpdateFilter = function(user, f) { return; } + if (f.replace.length > 1000) { + f.replace = f.replace.substring(0, 1000); + } + + if (f.flags.length > 4) { + f.flags = f.flags.substring(0, 4); + } + var re = f.source; var flags = f.flags; // Temporary fix @@ -2304,7 +2318,10 @@ Channel.prototype.tryUpdateMotd = function(user, data) { return; } - data.motd = data.motd || ""; + if (data.motd.length > 20000) { + data.motd = data.motd.substring(0, 20000); + } + this.updateMotd(data.motd); this.logger.log("%%% " + user.name + " set the MOTD"); } @@ -2432,29 +2449,6 @@ Channel.prototype.sendMessage = function (user, msg, meta, filter) { } }; -Channel.prototype.sendMessageOld = function(username, msg, msgclass, data) { - // I don't want HTML from strangers - msg = sanitize(msg).escape(); - msg = this.filterMessage(msg); - var msgobj = { - username: username, - msg: msg, - msgclass: msgclass, - time: Date.now() - }; - if(data) { - for(var key in data) { - msgobj[key] = data[key]; - } - } - this.sendAll("chatMsg", msgobj); - this.chatbuffer.push(msgobj); - if(this.chatbuffer.length > 15) - this.chatbuffer.shift(); - var unescaped = sanitize(msg).entityDecode(); - this.logger.log("<" + username + "." + msgclass + "> " + unescaped); -}; - /* REGION Rank stuff */ Channel.prototype.trySetRank = function(user, data) { diff --git a/lib/user.js b/lib/user.js index 800dd699..696e9391 100644 --- a/lib/user.js +++ b/lib/user.js @@ -314,7 +314,7 @@ User.prototype.initCallbacks = function () { } // Soft limit to prevent someone from making a massive query if (data.query.length > 255) { - return; + data.query = data.query.substring(0, 255); } if (data.source === "yt") { var searchfn = InfoGetter.Getters.ytSearch;