Using math/rand makes your passwords completely deterministic. Given
enough samples, an attacker will be able to predict all passwords
generated in the future. Since you also don't seed the prng, a default
seed of 1 is used, meaning the the same passwords will be generated
from the beginning whenever the server is restarted. In fact, the
attacker just has to query a single password and then run your
generation algorithm from the beginning until it finds the same
output. Everything after that will match.
As a very minor point, since rand.Int() is not evenly divisible by
len(alphabet), your output will have a tiny (and probably negligible)
bias toward the front of the alphabet.
Of the top of my head, a better approach would be to full a buffer
with random bytes from crypt/rand and then filter out any bytes that
are not in your alphabet.
- Max