4 ms·
Most plausible cause: uuid package depends on some random number generator package, which has recently been compromised in order to make “random” numbers predi
by jbverschoor 5mo ago
Most plausible cause: uuid package depends on some random number generator package, which has recently been compromised in order to make “random” numbers predictable. As a result, many crypto (ssl + currency) projects are compromised due to a supplychain attack.
- jbverschoor 5mo agoChanged 3 weeks ago: uuid/src/rng.ts : the random array is const. Every call will share the same random number. Subsequent call will update your old random code, so if you generated something important... good luck The old code used to do a slice() which creates a new copy. Might be unintentional. Although I have no idea how this would pass any tests, as you would think to test generating 2 randomnumbers and hope they are not the same.
- jbverschoor 5mo agoDidn't actually want to write a test myself.. but I miss Claudia confirmed it. Pretty concearning. Synchronous / serial calls: import rng from './rng'; const a = rng(); console.log('a after first call: ', Array.from(a)); const b = rng(); console.log('a after second call:', Array.from(a)); console.log('b after second call:', Array.from(b)); console.log('a === b (same reference)? ', a === b); console.log('a equals b (same contents)? ', a.every((v, i) => v === b[i])); output: a after first call: [ 101, 193, 125, 19, 142, 136, 181, 140, 209, 224, 176, 153, 179, 248, 246, 166 ] a after second call: [ 4, 29, 48, 215, 162, 60, 64, 23, 78, 137, 2, 186, 230, 249, 70, 224 ] b after second call: [ 4, 29, 48, 215, 162, 60, 64, 23, 78, 137, 2, 186, 230, 249, 70, 224 ] a === b (same reference)? true a equals b (same contents)? true and aynchronous calls: import rng from './rng'; async function getId() { const bytes = rng(); await new Promise(r => setTimeout(r, 0)); // yield to the event loop return Array.from(bytes); } const [id1, id2] = await Promise.all([getId(), getId()]); console.log('id1:', id1); console.log('id2:', id2); console.log('identical?', id1.every((v, i) => v === id2[i])); output: id1 captured: [ 61, 116, 151, 35, 153, 75, 105, 15, 59, 235, 162, 215, 224, 115, 31, 122 ] id2 captured: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] id1 after await: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] id2 after await: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] --- final id1: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] final id2: [ 13, 3, 84, 28, 22, 176, 160, 70, 67, 246, 1, 37, 38, 61, 171, 23 ] identical? true
- toraway 5mo agoShouldn't your test follow the pattern of how rng() is actually being used in the uuid.ts code internally? Your test is more-or-less contrived to fail given the tradeoff to avoid repeated memory allocations but that doesn't say much about the actual usage in uuid generation since it's not exported for general purpose use. Presumably they had some hot path somewhere where rng() is called in a loop and this optimization made sense with awareness that it could be misused as in your example breaking the contract ensuring randomness, which (hopefully) they're not actually doing anywhere. Unless I'm missing something replacing the package over this with a less vetted implementation seems excessive and possibly even counterproductive.
- jbverschoor 5mo agoI don't believe so. Sure it's not an issue after some checks, but it's very easy to shoot yourself in the foot like that. I get the micro-optimization for the allocation.. But it's not clear / documented. At the minimum, the function should be renamed to reflect the inner workings. The function is a module, and it doesn't do what you'd expect.
- jbverschoor 5mo agohttps://github.com/uuidjs/uuid/blob/e1f42a354593093ba0479f0b4047dae82d28c507/src/rng.ts https://github.com/uuidjs/uuid/blob/e1f42a354593093ba0479f0b... became https://github.com/uuidjs/uuid/blob/f2c235f93059325fa43e1106e624b5291bb523c4/src/rng.ts https://github.com/uuidjs/uuid/blob/f2c235f93059325fa43e1106... Welp.. time to patch and update everything again. Another day, another npm-package headache. Very odd() Attack vector: call the rng(), and send the result somewhere. You now have now overwritten someone elses "random number" and know about it. The fun things you can do with those numbers!
- jbverschoor 5mo agoSeems to be "safe" because of it's not exported, and the results get used in a different way. Still is a bug in my book.