mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 19:15:58 +01:00 
			
		
		
		
	refactor: replace math.random with crypto
This commit is contained in:
		| @@ -149,7 +149,7 @@ module.exports = function (Categories) { | ||||
| 	Categories.assignColours = function () { | ||||
| 		const backgrounds = ['#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946']; | ||||
| 		const text = ['#ffffff', '#ffffff', '#333333', '#ffffff', '#333333', '#ffffff', '#ffffff', '#ffffff']; | ||||
| 		const index = Math.floor(Math.random() * backgrounds.length); | ||||
| 		const index = utils.secureRandom(0, backgrounds.length - 1); | ||||
| 		return [backgrounds[index], text[index]]; | ||||
| 	}; | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,7 @@ const meta = require('../meta'); | ||||
| const plugins = require('../plugins'); | ||||
| const middleware = require('../middleware'); | ||||
| const helpers = require('../middleware/helpers'); | ||||
| const { secureRandom } = require('../utils'); | ||||
|  | ||||
| exports.handle404 = helpers.try(async (req, res) => { | ||||
| 	const relativePath = nconf.get('relative_path'); | ||||
| @@ -64,6 +65,6 @@ exports.send404 = helpers.try(async (req, res) => { | ||||
| 		path: validator.escape(path), | ||||
| 		title: '[[global:404.title]]', | ||||
| 		bodyClass: helpers.buildBodyClass(req, res), | ||||
| 		icon: icons[Math.floor(Math.random() * icons.length)], | ||||
| 		icon: icons[secureRandom(0, icons.length - 1)], | ||||
| 	}); | ||||
| }); | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| module.exports = function (module) { | ||||
| 	const _ = require('lodash'); | ||||
| 	const helpers = require('./helpers'); | ||||
| 	const { secureRandom } = require('../../utils'); | ||||
|  | ||||
| 	module.setAdd = async function (key, value) { | ||||
| 		if (!Array.isArray(value)) { | ||||
| @@ -200,7 +201,7 @@ module.exports = function (module) { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		const randomIndex = Math.floor(Math.random() * data.members.length); | ||||
| 		const randomIndex = secureRandom(0, data.members.length - 1); | ||||
| 		const value = data.members[randomIndex]; | ||||
| 		await module.setRemove(data._key, value); | ||||
| 		return value; | ||||
|   | ||||
| @@ -11,7 +11,11 @@ let cached; | ||||
|  | ||||
| // cache buster is an 11-character, lowercase, alphanumeric string | ||||
| function generate() { | ||||
| 	return (Math.random() * 1e18).toString(32).slice(0, 11); | ||||
| 	const crypto = require('crypto'); | ||||
| 	const length = 11; | ||||
| 	const generated = crypto.randomBytes(Math.ceil(length / 2)) | ||||
| 		.toString('hex').slice(0, length); | ||||
| 	return generated; | ||||
| } | ||||
|  | ||||
| exports.write = async function write() { | ||||
|   | ||||
| @@ -29,7 +29,9 @@ async function getFakeHash() { | ||||
| 	if (fakeHashCache) { | ||||
| 		return fakeHashCache; | ||||
| 	} | ||||
| 	fakeHashCache = await exports.hash(12, Math.random().toString()); | ||||
| 	const length = 18; | ||||
| 	fakeHashCache = crypto.randomBytes(Math.ceil(length / 2)) | ||||
| 		.toString('hex').slice(0, length); | ||||
| 	return fakeHashCache; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -46,10 +46,10 @@ SocketUser.reset.send = async function (socket, email) { | ||||
| 	try { | ||||
| 		await user.reset.send(email); | ||||
| 		await logEvent('[[success:success]]'); | ||||
| 		await sleep(2500 + ((Math.random() * 500) - 250)); | ||||
| 		await sleep(2500 + (utils.secureRandom(0, 500) - 250)); | ||||
| 	} catch (err) { | ||||
| 		await logEvent(err.message); | ||||
| 		await sleep(2500 + ((Math.random() * 500) - 250)); | ||||
| 		await sleep(2500 + (utils.secureRandom(0, 500) - 250)); | ||||
| 		const internalErrors = ['[[error:invalid-email]]']; | ||||
| 		if (!internalErrors.includes(err.message)) { | ||||
| 			throw err; | ||||
|   | ||||
							
								
								
									
										10
									
								
								src/utils.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/utils.js
									
									
									
									
									
								
							| @@ -31,6 +31,16 @@ utils.generateUUID = function () { | ||||
| 	return rnd.join('-'); | ||||
| }; | ||||
|  | ||||
| utils.secureRandom = function (low, high) { | ||||
| 	if (low > high) { | ||||
| 		throw new Error("The 'low' parameter must be less than or equal to the 'high' parameter."); | ||||
| 	} | ||||
| 	const randomBuffer = crypto.randomBytes(4); | ||||
| 	const randomInt = randomBuffer.readUInt32BE(0); | ||||
| 	const range = high - low + 1; | ||||
| 	return low + (randomInt % range); | ||||
| }; | ||||
|  | ||||
| utils.getSass = function () { | ||||
| 	try { | ||||
| 		const sass = require('sass-embedded'); | ||||
|   | ||||
| @@ -102,7 +102,7 @@ describe('Utility Methods', () => { | ||||
| 		}); | ||||
| 	}); | ||||
|  | ||||
| 	describe('UUID generation', () => { | ||||
| 	describe('UUID generation / secureRandom', () => { | ||||
| 		it('return unique random value every time', () => { | ||||
| 			delete require.cache[require.resolve('../src/utils')]; | ||||
| 			const { generateUUID } = require('../src/utils'); | ||||
| @@ -110,6 +110,19 @@ describe('Utility Methods', () => { | ||||
| 			const uuid2 = generateUUID(); | ||||
| 			assert.notEqual(uuid1, uuid2, 'matches'); | ||||
| 		}); | ||||
|  | ||||
| 		it('should return a random number between 1-10 inclusive', () => { | ||||
| 			const { secureRandom } = require('../src/utils'); | ||||
| 			const r1 = secureRandom(1, 10); | ||||
| 			assert(r1 >= 1); | ||||
| 			assert(r1 <= 10); | ||||
| 		}); | ||||
|  | ||||
| 		it('should always return 3', () => { | ||||
| 			const { secureRandom } = require('../src/utils') | ||||
| 			const r1 = secureRandom(3, 3); | ||||
| 			assert.strictEqual(r1, 3); | ||||
| 		}); | ||||
| 	}); | ||||
|  | ||||
| 	describe('cleanUpTag', () => { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user