mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
introduce query to detect biased random number generators
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
| bad-random.js:3:11:3:61 | crypto. ... s(1)[0] | Using addition on cryptographically random numbers produces biased results. |
|
||||
| bad-random.js:4:11:4:61 | crypto. ... s(1)[0] | Using multiplication on cryptographically random numbers produces biased results. |
|
||||
| bad-random.js:9:28:9:43 | buffer[i] / 25.6 | Using division on cryptographically random numbers produces biased results. |
|
||||
| bad-random.js:11:17:11:31 | buffer[i] % 100 | Using modulo on cryptographically random numbers produces biased results. |
|
||||
| bad-random.js:14:11:14:63 | Number( ... (0, 3)) | Using string concatenation on cryptographically random numbers produces biased results. |
|
||||
| bad-random.js:73:32:73:42 | byte / 25.6 | Using division on cryptographically random numbers produces biased results. |
|
||||
| bad-random.js:75:21:75:30 | byte % 100 | Using modulo on cryptographically random numbers produces biased results. |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-327/BadRandomness.ql
|
||||
@@ -0,0 +1,77 @@
|
||||
const crypto = require('crypto');
|
||||
|
||||
var bad = crypto.randomBytes(1)[0] + crypto.randomBytes(1)[0]; // NOT OK
|
||||
var bad = crypto.randomBytes(1)[0] * crypto.randomBytes(1)[0]; // NOT OK
|
||||
|
||||
const buffer = crypto.randomBytes(bytes);
|
||||
const digits = [];
|
||||
for (let i = 0; i < buffer.length; ++i) {
|
||||
digits.push(Math.floor(buffer[i] / 25.6)); // NOT OK
|
||||
digits.push(buffer[i] % 8); // OK - 8 is a power of 2, so the result is unbiased.
|
||||
digits.push(buffer[i] % 100); // NOT OK
|
||||
}
|
||||
|
||||
var bad = Number('0.' + crypto.randomBytes(3).readUIntBE(0, 3)); // NOT OK
|
||||
var good = Number(10 + crypto.randomBytes(3).readUIntBE(0, 3)); // OK
|
||||
|
||||
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); // GOOD - 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); // GOOD - 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)); // NOT OK
|
||||
digits.push(byte % 8); // OK - 8 is a power of 2, so the result is unbiased.
|
||||
digits.push(byte % 100); // NOT OK
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user