Generally, the random function is not cryptographically strong, for that you need to make sure you are using a cryptographic pseudo-random-number generator.
Generic random functions generally don't use cryptographically strong generation methods because they take longer than simple ones, (eg. Yarrow is more complicated than Mersenne Twister) and require careful management of the entropy pool, which is not a guarantee that Mozilla, cstdlib, etc. want to make to you.
If you need access to cryptographically strong random number generators, I'd look into getting access to the underlying SSL implementation (which a given browser may or may not allow access to).
Recent browsers expose
window.crypto.getRandomValues() which is cryptographically strong.
There are also JS libraries that implement strong RNGs but without
getRandomValues() it's very hard part to collect entropy. It can be done from mouse & keyboard though it may take a long time.
Math.random() was weak in most browsers in 2008 - Amit Klein's paper goes into excellent detail - and sadly is almost as weak today.
UPDATE: It seems practically all browsers switched in 2015–2016 to XorShift128+ — a fast variant on LFSR tuned to good statistical properties but also very weak cryptographically: https://lwn.net/Articles/666407/, https://security.stackexchange.com/questions/84906/predicting-math-random-numbers. Details below are out of date.
Firefox used a very weak "our own homebrew LFSR" algorithm; they've been discussing switching to a stronger algoritm and entropy source since 2006 (bug 322529). UPDATE: in 2015 they switched to XorShift128+.
In May 2013 they at least switched the seed from current time to good entropy sources (bug 868860), also removing(?) cross-tab leakage.
Webkit uses a weak fast algorithm (GameRand) since 2009 but seeds since 2010 (in each context) from a strong RNG initialized from strong OS sources.
(I presume this is what Safari uses but I may be confused about the various WebKit ports...)
Not sure how it's seeded. V8 has SetEntropySource() hook, but apparently it was only introduced for unit testing, not called by Chrome. If not called,
random() is used for seeding.
State became per-context in 2011 but that's not very useful with weak seeding.
Didn't find documentation on what IE does nowdays. They had a weak linear PRNG in 2008 (see paper). They did tell Amit they'll fix it in a service pack, so there might be an advisory somewhere...
If you need a good source of entropy in a browser (and preferably don't need it very often), I would recommend capturing mouse movement data and running it through a cryptographically-strong hashing algorithm. Existing programs such as the Entropy Gathering Daemon (used with gpg) can be used as a reference for how to implement such a system.
©2020 All rights reserved.