Skip to content

Commit 3babf67

Browse files
authored
Merge pull request #3824 from Countly/SER-482-vulnerable-password-generation
[SER-482] vulnerable password generation
2 parents 1c4d0e3 + b096c5c commit 3babf67

File tree

2 files changed

+85
-29
lines changed

2 files changed

+85
-29
lines changed

api/utils/common.js

+43-14
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,44 @@ common.reviver = (key, value) => {
26102610
}
26112611
};
26122612

2613+
/**
2614+
* Shuffle string using crypto.getRandomValues
2615+
* @param {string} text - text to be shuffled
2616+
* @returns {string} shuffled password
2617+
*/
2618+
common.shuffleString = function(text) {
2619+
var j, x, i;
2620+
for (i = text.length; i; i--) {
2621+
j = Math.floor(Math.random() * i);
2622+
x = text[i - 1];
2623+
text[i - 1] = text[j];
2624+
text[j] = x;
2625+
}
2626+
2627+
return text.join("");
2628+
};
2629+
2630+
/**
2631+
* Gets a random string from given character set string with given length
2632+
* @param {string} charSet - charSet string
2633+
* @param {number} length - length of the random string. default 1
2634+
* @returns {string} random string from charset
2635+
*/
2636+
common.getRandomValue = function(charSet, length = 1) {
2637+
const randomValues = crypto.getRandomValues(new Uint8Array(charSet.length));
2638+
let randomValue = "";
2639+
2640+
if (length > charSet.length) {
2641+
length = charSet.length;
2642+
}
2643+
2644+
for (let i = 0; i < length; i++) {
2645+
randomValue += charSet[randomValues[i] % charSet.length];
2646+
}
2647+
2648+
return randomValue;
2649+
};
2650+
26132651
/**
26142652
* Generate random password
26152653
* @param {number} length - length of the password
@@ -2631,29 +2669,20 @@ common.generatePassword = function(length, no_special) {
26312669
}
26322670

26332671
//1 char
2634-
text.push(upchars.charAt(Math.floor(Math.random() * upchars.length)));
2672+
text.push(this.getRandomValue(upchars));
26352673
//1 number
2636-
text.push(numbers.charAt(Math.floor(Math.random() * numbers.length)));
2674+
text.push(this.getRandomValue(numbers));
26372675
//1 special char
26382676
if (!no_special) {
2639-
text.push(specials.charAt(Math.floor(Math.random() * specials.length)));
2677+
text.push(this.getRandomValue(specials));
26402678
length--;
26412679
}
26422680

2643-
var j, x, i;
26442681
//5 any chars
2645-
for (i = 0; i < Math.max(length - 2, 5); i++) {
2646-
text.push(all.charAt(Math.floor(Math.random() * all.length)));
2647-
}
2682+
text.push(this.getRandomValue(all, Math.max(length - 2, 5)));
26482683

26492684
//randomize order
2650-
for (i = text.length; i; i--) {
2651-
j = Math.floor(Math.random() * i);
2652-
x = text[i - 1];
2653-
text[i - 1] = text[j];
2654-
text[j] = x;
2655-
}
2656-
return text.join("");
2685+
return this.shuffleString(text);
26572686
};
26582687

26592688
/**

frontend/express/public/javascripts/countly/countly.helpers.js

+42-15
Original file line numberDiff line numberDiff line change
@@ -3354,6 +3354,43 @@
33543354
$(".select-items").hide();
33553355
});
33563356
};
3357+
/**
3358+
* Shuffle string using crypto.getRandomValues
3359+
* @param {string} text - text to be shuffled
3360+
* @returns {string} shuffled password
3361+
*/
3362+
CountlyHelpers.shuffleString = function(text) {
3363+
var j, x, i;
3364+
for (i = text.length; i; i--) {
3365+
j = Math.floor(Math.random() * i);
3366+
x = text[i - 1];
3367+
text[i - 1] = text[j];
3368+
text[j] = x;
3369+
}
3370+
3371+
return text.join("");
3372+
3373+
};
3374+
/**
3375+
* Gets a random string from given character set string with given length
3376+
* @param {string} charSet - charSet string
3377+
* @param {number} length - length of the random string. default 1
3378+
* @returns {string} random string from charset
3379+
*/
3380+
CountlyHelpers.getRandomValue = function(charSet, length = 1) {
3381+
const randomValues = crypto.getRandomValues(new Uint8Array(charSet.length));
3382+
let randomValue = "";
3383+
3384+
if (length > charSet.length) {
3385+
length = charSet.length;
3386+
}
3387+
3388+
for (let i = 0; i < length; i++) {
3389+
randomValue += charSet[randomValues[i] % charSet.length];
3390+
}
3391+
3392+
return randomValue;
3393+
};
33573394

33583395
/**
33593396
* Generate random password
@@ -3376,30 +3413,20 @@
33763413
}
33773414

33783415
//1 char
3379-
text.push(upchars.charAt(Math.floor(Math.random() * upchars.length)));
3416+
text.push(this.getRandomValue(upchars));
33803417
//1 number
3381-
text.push(numbers.charAt(Math.floor(Math.random() * numbers.length)));
3418+
text.push(this.getRandomValue(numbers));
33823419
//1 special char
33833420
if (!no_special) {
3384-
text.push(specials.charAt(Math.floor(Math.random() * specials.length)));
3421+
text.push(this.getRandomValue(specials));
33853422
length--;
33863423
}
33873424

3388-
var j, x, i;
33893425
//5 any chars
3390-
for (i = 0; i < Math.max(length - 2, 5); i++) {
3391-
text.push(all.charAt(Math.floor(Math.random() * all.length)));
3392-
}
3426+
text.push(this.getRandomValue(all, Math.max(length - 2, 5)));
33933427

33943428
//randomize order
3395-
for (i = text.length; i; i--) {
3396-
j = Math.floor(Math.random() * i);
3397-
x = text[i - 1];
3398-
text[i - 1] = text[j];
3399-
text[j] = x;
3400-
}
3401-
3402-
return text.join("");
3429+
return this.shuffleString(text);
34033430
};
34043431

34053432
/**

0 commit comments

Comments
 (0)