mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
129 lines
5.0 KiB
JavaScript
129 lines
5.0 KiB
JavaScript
const crypto = require('crypto');
|
|
|
|
var bad = crypto.randomBytes(1)[0] + crypto.randomBytes(1)[0]; // $ Alert[js/biased-cryptographic-random]
|
|
var bad = crypto.randomBytes(1)[0] * crypto.randomBytes(1)[0]; // $ Alert[js/biased-cryptographic-random]
|
|
|
|
const buffer = crypto.randomBytes(bytes);
|
|
const digits = [];
|
|
for (let i = 0; i < buffer.length; ++i) {
|
|
digits.push(Math.floor(buffer[i] / 25.6)); // $ Alert[js/biased-cryptographic-random]
|
|
digits.push(buffer[i] % 8); // OK - input is a random byte, so the output is a uniformly random number between 0 and 7.
|
|
digits.push(buffer[i] % 100); // $ Alert[js/biased-cryptographic-random]
|
|
}
|
|
|
|
var bad = Number('0.' + crypto.randomBytes(3).readUIntBE(0, 3)); // $ Alert[js/biased-cryptographic-random]
|
|
var good = Number(10 + crypto.randomBytes(3).readUIntBE(0, 3));
|
|
|
|
const internals = {};
|
|
exports.randomDigits = function (size) {
|
|
const digits = [];
|
|
|
|
let buffer = internals.random(size * 2);
|
|
let pos = 0;
|
|
|
|
while (digits.length < size) {
|
|
if (pos >= buffer.length) {
|
|
buffer = internals.random(size * 2);
|
|
pos = 0;
|
|
}
|
|
|
|
if (buffer[pos] < 250) {
|
|
digits.push(buffer[pos] % 10); // OK - protected by a bias-checking comparison.
|
|
}
|
|
++pos;
|
|
}
|
|
|
|
return digits.join('');
|
|
};
|
|
|
|
internals.random = function (bytes) {
|
|
try {
|
|
return crypto.randomBytes(bytes);
|
|
}
|
|
catch (err) {
|
|
throw new Error("Failed to make bits.");
|
|
}
|
|
};
|
|
|
|
exports.randomDigits2 = function (size) {
|
|
const digits = [];
|
|
|
|
let buffer = crypto.randomBytes(size * 2);
|
|
let pos = 0;
|
|
|
|
while (digits.length < size) {
|
|
if (pos >= buffer.length) {
|
|
buffer = internals.random(size * 2);
|
|
pos = 0;
|
|
}
|
|
var num = buffer[pos];
|
|
if (num < 250) {
|
|
digits.push(num % 10); // OK - protected by a bias-checking comparison.
|
|
}
|
|
++pos;
|
|
}
|
|
|
|
return digits.join('');
|
|
};
|
|
|
|
function setSteps() {
|
|
const buffer = crypto.randomBytes(bytes);
|
|
const digits = [];
|
|
for (const byte of buffer.values()) {
|
|
digits.push(Math.floor(byte / 25.6)); // $ Alert[js/biased-cryptographic-random]
|
|
digits.push(byte % 8); // OK - 8 is a power of 2, so the result is unbiased.
|
|
digits.push(byte % 100); // $ Alert[js/biased-cryptographic-random]
|
|
}
|
|
}
|
|
|
|
const secureRandom = require("secure-random");
|
|
|
|
var bad = secureRandom(10)[0] + secureRandom(10)[0]; // $ Alert[js/biased-cryptographic-random]
|
|
|
|
var goodRandom1 = 5 + secureRandom(10)[0];
|
|
var goodRandom2 = 5 + secureRandom(10)[0];
|
|
var bad = goodRandom1 + goodRandom2; // $ Alert[js/biased-cryptographic-random]
|
|
|
|
var dontFlag = bad + bad; // $ Alert[js/biased-cryptographic-random] - OK - the operands have already been flagged - but flagged anyway due to us not detecting that [INCONSISTENCY].
|
|
|
|
var good = secureRandom(10)[0] / 0xff; // OK - result is not rounded.
|
|
var good = Math.ceil(0.5 - (secureRandom(10)[0] / 25.6)); // $ Alert[js/biased-cryptographic-random] - division generally introduces bias - but not flagged due to not looking through nested arithmetic.
|
|
|
|
var good = (crypto.randomBytes(1)[0] << 8) + crypto.randomBytes(3)[0]; // OK - bit shifts are usually used to construct larger/smaller numbers,
|
|
|
|
var good = Math.floor(max * (crypto.randomBytes(1)[0] / 0xff)); // OK - division by 0xff (255) gives a uniformly random number between 0 and 1.
|
|
|
|
var bad = Math.floor(max * (crypto.randomBytes(1)[0] / 100)); // $ Alert[js/biased-cryptographic-random] - division by 100 gives bias - but not flagged due to not looking through nested arithmetic.
|
|
|
|
var crb = crypto.randomBytes(4);
|
|
var cryptoRand = 0x01000000 * crb[0] + 0x00010000 * crb[1] + 0x00000100 * crb[2] + 0x00000001 * crb[3]; // OK - producing a larger number from smaller numbers.
|
|
|
|
var good = (secureRandom(10)[0] + "foo") + (secureRandom(10)[0] + "bar"); // OK - string concat
|
|
|
|
var eight = 8;
|
|
var good = crypto.randomBytes(4)[0] % eight; // OK - modulo by power of 2.
|
|
|
|
var twoHundredAndFiftyFive = 0xff;
|
|
var good = Math.floor(max * (crypto.randomBytes(1)[0] / twoHundredAndFiftyFive)); // OK - division by 0xff (255) gives a uniformly random number between 0 and 1.
|
|
|
|
var a = crypto.randomBytes(10);
|
|
var good = ((a[i] & 31) * 0x1000000000000) + (a[i + 1] * 0x10000000000) + (a[i + 2] * 0x100000000) + (a[i + 3] * 0x1000000) + (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6]; // OK - generating a large number from smaller bytes.
|
|
var good = (a[i] * 0x100000000) + a[i + 6]; // OK - generating a large number from smaller bytes.
|
|
var good = (a[i + 2] * 0x10000000) + a[i + 6]; // OK - generating a large number from smaller bytes.
|
|
var foo = 0xffffffffffff + 0xfffffffffff + 0xffffffffff + 0xfffffffff + 0xffffffff + 0xfffffff + 0xffffff
|
|
|
|
// Bad documentation example:
|
|
const digits = [];
|
|
for (let i = 0; i < 10; i++) {
|
|
digits.push(crypto.randomBytes(1)[0] % 10); // $ Alert[js/biased-cryptographic-random]
|
|
}
|
|
|
|
// Good documentation example:
|
|
const digits = [];
|
|
while (digits.length < 10) {
|
|
const byte = crypto.randomBytes(1)[0];
|
|
if (byte >= 250) {
|
|
continue;
|
|
}
|
|
digits.push(byte % 10);
|
|
} |