diff --git a/src/app/chatPreprocessor.js b/src/app/chatPreprocessor.js index be7cf26..a4331ab 100644 --- a/src/app/chatPreprocessor.js +++ b/src/app/chatPreprocessor.js @@ -132,7 +132,6 @@ class chatPreprocessor{ commandObj.links = []; //For each link sent from the client - //this.rawData.links.forEach((link) => { for (const link of commandObj.rawData.links){ //Add a marked link object to our links array commandObj.links.push(await linkUtils.markLink(link)); diff --git a/src/schemas/user/userBanSchema.js b/src/schemas/user/userBanSchema.js index 0c1db1c..0fd352c 100644 --- a/src/schemas/user/userBanSchema.js +++ b/src/schemas/user/userBanSchema.js @@ -73,8 +73,6 @@ const userBanSchema = new mongoose.Schema({ * @returns {Mongoose.Document} Found ban Document if one exists. */ userBanSchema.statics.checkBanByIP = async function(ip){ - //Get hash of ip - const ipHash = hashUtil.hashIP(ip); //Get all bans const banDB = await this.find({}); //Create null variable to hold any found ban @@ -106,7 +104,7 @@ userBanSchema.statics.checkBanByIP = async function(ip){ const curHash = ban.ips.hashed[ipIndex]; //Check the current hash against the given hash - if(ipHash == curHash){ + if(hashUtil.compareIPHash(ip, curHash)){ //If it matches we found the ban foundBan = ban; diff --git a/src/schemas/user/userSchema.js b/src/schemas/user/userSchema.js index 2d8517c..41dfcda 100644 --- a/src/schemas/user/userSchema.js +++ b/src/schemas/user/userSchema.js @@ -757,8 +757,6 @@ userSchema.methods.tattooIPRecord = async function(ip){ lastLog: new Date() }; - //We should really start using for loops and stop acting like its 2008 - //Though to be quite honest this bit would be particularly brutal without them //For every user in the userlist for(let curUser of users){ //Ensure we're not checking the user against itself @@ -766,7 +764,7 @@ userSchema.methods.tattooIPRecord = async function(ip){ //For every IP record in the current user for(let curRecord of curUser.recentIPs){ //If it matches the current ipHash - if(curRecord.ipHash == ipHash){ + if(hashUtil.compareIPHash(ip, curRecord.ipHash)){ //Check if we've already marked the user as an alt const foundAlt = this.alts.indexOf(curUser._id); @@ -803,7 +801,7 @@ userSchema.methods.tattooIPRecord = async function(ip){ //Look for matching ip record function checkHash(ipRecord){ //return matching records - return ipRecord.ipHash == ipHash; + return hashUtil.compareIPHash(ip, ipRecord.ipHash); } } diff --git a/src/utils/hashUtils.js b/src/utils/hashUtils.js index e60d81e..a428066 100644 --- a/src/utils/hashUtils.js +++ b/src/utils/hashUtils.js @@ -60,17 +60,40 @@ module.exports.compareLegacyPassword = function(pass, hash){ * * Provides a basic level of privacy by only logging salted hashes of IP's * @param {String} ip - IP to hash - * @returns {String} Hashed/Peppered IP Adress + * @param {String} salt - (optional) string to salt IP with, leave empty to default to a securely generated string encoded in base64 + * @returns {String} Hashed/Peppered/Salted IP Address */ -module.exports.hashIP = function(ip){ +module.exports.hashIP= function(ip, salt){ //Create hash object const hashObj = crypto.createHash('sha512'); - //add IP and pepper to the hash - hashObj.update(`${ip}${config.secrets.ipSecret}`); + //If we wheren't provided salt + if(salt == null){ + //Generate salt with cryptographically secure rng function + const rawSalt = crypto.randomBytes(24); + //Convert generated salt to base64 + salt = rawSalt.toString('base64'); + } - //return the IP hash as a string - return hashObj.digest('hex'); + //Generate new salted hash + hashObj.update(`${ip}${config.secrets.ipSecret}${salt}`); + + //Convert hash data into a base64 string + const hash = hashObj.digest('base64'); + + //Return salty hash + return `${salt}$${hash}`; +} + +module.exports.compareIPHash = function(ip, hash){ + //Split hash by salt delimiter + const splitHash = hash.split("$"); + + //Re-generate hash from received plaintext IP and salt scraped from existing hash + const tempHash = module.exports.hashIP(ip, splitHash[0]); + + //If the hash we calculates matches the original + return tempHash == hash; } /**