question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Regression: Stub pseudo randomness broken

See original GitHub issue

Describe the bug

Stubbing of pseudo randomness no longer feasible / working with this change

The below example works reliably with 8.3.0 but breaks with 8.3.1

How to reproduce

const crypto = require('crypto');
const { v4: uuid } = require('uuid');

crypto.randomBytes = (size, cb) => {
  let result = crypto.createHash('sha256').update('some-seed').digest();
  while (result.length < size) {
    result = Buffer.concat([result, crypto.createHash('sha256').update(result).digest()]);
  }
  result = result.slice(0, size);
  return cb ? cb(null, result) : result;
};
crypto.randomFillSync = (buffer, offset, size) => {
  const o = offset || 0;
  const s = size || buffer.byteLength;
  crypto.randomBytes(s, (err, res) => {
    res.copy(buffer, o, 0, s);
  });
  return buffer;
};

console.log(uuid(), uuid());
// => 0ad40e47-01e4-4acb-afa0-ad8c30a6aa42, 0ad40e47-01e4-4acb-afa0-ad8c30a6aa42

Above can probably be made even more minimal. The example was distilled from here.

Expected behavior

It should be feasible to stub the uuid generation with a PRNG at any given point in time. With the optimization introduces in 8.3.1 this is no longer possible without re-requiring uuid before every randomness “reset”.

Runtime

  • OS: Linux
  • Runtime: Node.js
  • Runtime Version: v10.22.1

Additional information

Background: I’m the maintainer of a test framework that supports pseudo randomness injection. The use case of making uuid generation consistent between test executions is very important to us to e.g. make requests fingerprints consistent since we are using nock.

I’m sure the discussion above is going to go towards “why is above example even necessary”, ie it should be enough to seed once? The problem is that state was introduced with uuid v8.3.1. So randomness can no longer be “reset” when necessary (i.e. between running different tests). That means that to reset the randomness state one needs to re-require the uuid import. This is very ugly and leads to memory leaks.

I am very happy to explain this further and give more background if needed!

Maybe there is a way that we can do both: keep the ability for stubbing as well as the optimization that was introduced. But I’m not sure how just yet. Very much looking forward to having a good discussion here. Cheers!

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:16 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
ctavancommented, Aug 13, 2022

I think that adding an option to disable the randomness cache, in line with what the standard now provides, makes a lot of sense!

Anyone interested in contributing a PR?

I think this should also allow to stub the library again, wdyt @simlu ?

I‘m also glad to hear that crypto.randomUUID() from the standard library works for you! Introducing this to the standard library to allow folks get rid of the uuid npm dependency was exactly our intention.

1reaction
puzpuzpuzcommented, Oct 7, 2020

@simlu it’s very hard to argue against a bad vibe, but I’ll try.

Scenario 1 was exactly the same before #513, as the buffer was reused since #435. And even before that the buffer could be still available on heap until it’s eventually overwritten during GC compaction or new objects.

As for the scenario 2, I don’t quite understand what’s meant by “user logged into a program”. Is it a OS-level user log in event or something else? How both users are supposed to copy the pool? A heap dump, a core dump, or something else? If one of the two versions, the previous version of the library was also vulnerable to this kind of attack.

Considering how widespread this library is used, I’d recommend an immediate rollback and potentially an npm audit report for this version…

I thought that this issue is dedicated to a broken mocking library. Probably, it makes sense to open another security-related issue and provide some concrete examples of new attack vectors introduced by the change. But that’s just an advice and maintainers of this library may think otherwise.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Developers - Regression: Stub pseudo randomness broken -
Coming soon: A brand new website interface for an even better experience!
Read more >
Randomness in Your Poker Results? Don't Forget ...
"Regression to the mean" is a concept worth knowing, especially for poker players trying to assess their results, especially big upswings ...
Read more >
Unit testing - how do I test a function that returns random output?
If the randomness is based on a random number generator that it calls, you can rig up a stub random() function that returns...
Read more >
Postestimation tools for mixed - Stata
of random-effects terms in the model (or level). However, it is much easier to just specify stub* and let Stata name the variables...
Read more >
Coherent Consciousness and Reduced Randomness:
The GCP maintains a network of random event generators (REGs) located in some ... towers of the World Trade Center (WTC) and severely...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found