1. 8
  1.  

  2. 5

    Better naming could help here: naming it insecure_random() instead of random() would be a lot better, IMO.

    Especially in Go this is a bit of an issue, because rand.Read() can be either a CSPRNG or not, which depends on whether you import math/rand or crypto/rand: it’s not at all obvious by just looking at a function (and copy/pasting just the function may transform a CSPRNG to a non-secure RNG if the import changes by accident!)

    1. 3

      I think there are two use cases for a pseudorandom number generator and random doesn’t actually meet either of them:

      • A cryptographically secure source that an be used to generate keys, nonces and so on.
      • A reproduceable sequence of number that don’t follow an obvious pattern.

      The second is very useful for a lot of debugging cases and for generating data for programs (my favourite example of this is the galaxy generation in Elite) and so on. Unfortunately, random is not portable across platforms because the algorithm is not specified and it is not composeable because it is internally stateful and so you don’t get a reliable sequence if anything else calls it.

      1. 1

        There are more, but the interface has similar problems as malloc. You never just want “memory”, there is something more to it that is being lost in abstraction - alignment, zero-state, content type, device attachment, life-span and so on are afterthoughts rather than natural parts of the interface itself.

        True uniform random is somewhat useless in graphics, while ‘random’ enough is good for procedural stuff. Unlikely intended as such, but perhaps the term ‘noise’ is better than ‘random’ also for ‘reproducible sequence of numbers’ (with a user controlled seed that is not necessarily a key).

      2. 1

        I’ve also had some golang security linter incorrectly identify which rand lib I’ve been using. Very annoying.

      3. 4

        I see commenters here aren’t reading the article. The answer is no…

        Still, I absolutely love the process they used to come to that conclusion. I can think of a lot of problems with fix rate, but it’s still so much better than any other data driven approach to this problem that I’ve seen. I’ll see if I can implement it for other non-security related things.

        1. 3

          Yes please! Once again it’s a non issue on OpenBSD.

          Standards insist that this interface return deterministic results. Unsafe usage is very common, so OpenBSD changed the subsystem to return non-deterministic results by default. If the standardized behavior is required srandom_deterministic() can be used.

            1. 1

              Notably, even in security contexts plain PRNG’s can be useful. For example, I’m working on a cryptography project in Python, and I’m using the default random() there for getting randomness from seeded values that isn’t used for security purposes.

              1. 1

                Even then, you may wish to use a seeded CSPRNG (I don’t know if that’s actually the right term, but I think you know what I mean). I have found that the quality (by which I mean a lack of patterns in the output) of the insecure random can be remarkably bad.

                Several years ago a colleague was using Go’s math/rand to generate some testing data, and he noticed some really strange patterns in it. Swapped in crypto/rand and the problem went completely away.

                That was great, but of course not seedable, which can be important for repeatability or deterministic builds. But a simple high-quality seedable generator is easily built from a block cypher in counter mode, which can sometimes be exactly what is needed.

                1. 1

                  Of course, the size of the PRNG state and the quality of it are very important depending on the application. Considering that I will only use ~1000 bytes at most of data from a single seed(that is from a secure random source) and that Python’s random implementation uses a Mersenne Twister with a period of 2**19937-1 I think my use case doesn’t have to worry about most of the pitfalls of a PRNG. On the other hand, Go’s math/rand generator seems to have a bunch of problems.

              2. 1

                I just did my first C project and I made an error with it and it wasn’t even about security. I needed seeded determinism. It was for a plugin in a larger program and I guess it had an interrupt somewhere which uses random() because the results would sometimes differ near the end of the sequence.

                Ban it, it’s too easily misunderstood.