archive_me1Add my vote for this tag create new tag
, view all tags

Better Password Generation (DEVELOP)


The code used to generate 'new system generated passwords' in Dakar as of 3889 is very simplistic:

# global used by test harness to give predictable results
use vars qw( $password );
# STATIC function that returns a random password
sub randomPassword {
    return $password || int( rand(9999) );

I have observer that in practice this give a large number of new passwords of the form XYYZ, that is the middle two digits being the same. I don't know why this is.

The second motivating factor is the limits of the password storage and generation system, its implicit and exlicit assumptions.

Implicit and Explicit Constraints

  • Apache basic authentication is so simple and straightforward most sites will use it rather than install LDAP databases.
  • Cleartext passwords are not stored, so cannot be stolen.
    This is a good thing, but requires the geenration of a new password if the user forgets his old one.
  • The Apache .htpasswd file is stored, by default, under $cfg{DataDir} as defined by the line
    $cfg{HtpasswdFileName} = "$cfg{DataDir}/.htpasswd";
    in lib/TWiki.cfg. This is within TWiki's "address space", which is a weakness. The file has encrypted passwords, but the 'crypt' algorithm is comparatively weak and has been replaced by stronger ones in, for example, the UNIX password system.
  • TWiki's own code is used to manipulate the the .htpasswd file rather than the external command or the CPAN module =Apache::HtPasswd
    • There is growing evidence that this TWiki code has compatibility problems - see PasswordsAreMangled
  • When a user who has forgotten his/her password requests a new one or when the system administrator performs a password reset using BulkPasswordReset, the new password(s) are sent to the users by e-mail.
    • This is a limited risk. Apart, possibly from the Echelon project, there is no evidence of e-mail being intercepted in transit. We have good, high speed networks and connectivity. However there is a risk at end points, that POP and IMAP servers might have a window of vulnerability until the e-mail is downloaded. Other services such as G-Mail, AOL and others who have additional services or odd terms of service may present a much larger risk.
    • Sending the new password to the user's e-mail address only makes sense if the e-mail address cannot be hacked. The e-mail address is in the users home topic. At present, when these are generated, ther is no access control setting that prevents anyone, even TWikiGuest, from altering the address to their own mailbox, requesting the password, then altering it back. This is a matter for a separate bug report.

  • There is the assumption that once the user has been given the new four-digit password he/she will log in and change it to soemthng more memorable and more complex.
    I do not think this assumption is valid
    • Unlike UNIX and MS-Windows systems there is no mechanism that forces a "change password after first use following administrative reset". The use could continue to use the weak 4-digit password indefinitely.

The code that generates the unique URL for the edit function is a good bit better.


  • I do not see a way to enforce a "change password after first use following administrative reset" without a great deal of session tracking.

  • We do not have the necessary infrastrucure to deal with encrypted, signed E-mail from arbitrary internet based users.

  • We must ensure that all user topics and all newly generated user topics have the ALLOWTOPICCHANGE set to ensure the topic can only be edited by the owner.

Code Suggestion 1

This is just a longer version of the curent implementation. It is still numeric. It is a minimal change.

# STATIC function that returns a random password
sub randomPassword {
    return $password || sprintf("%x%lx", rand(0xffff), rand(0xffffffff) ) ;


Code Suggestion 2

This is a much larger change and can be used to produce passwords of minimum length and arbitrary mix of charectars. It has two "advantages':

  1. The password is _un-_memorable enough that there is a high incentive to change it
  2. If it isn't changed then it is fairly 'strong'

# STATIC function that returns a random password
sub randomPassword {
    my @alphabet = (
                '0' .. '9', ';', '+', '=',
                '!', '@', '#', '$', '%', '^', '&', '*',
                '(', ')', '<', '>', ',', '.', '?', '/',
                'a' .. 'z',
                'A' .. 'Z',
                'Af', 'pfish', 'CzC', 'Oz0', ':-)', '^oOo^', '@=@'   # supports poly-glyphs as well
                  ) ;
    my $passwd = '';
    for  (1 ..8) {
         $passwd .= $alphabet[rand(@alphabet)];
    return $passwd ;


This isn't really a solution. Passwords are not really a secure solution, they are just something that is easy to implement and widely recognised by the user community. The trend at the corporate level is towards alernate methods such as biometrics and two-factor. Even microsft has announced it is heading that way.

See Also

which I very strongly recommend. http://www.amazon.com/exec/obidos/tg/detail/-/0201615991/qid=1076093927//ref=pd_ka_1/104-7164757-9909538?v=glance&s=books&n=507846 (I've had two copies stolen so far.)

-- AntonAylward - 26 Mar 2005


I've tried, in turn, removing the "default static" value from the expression and adding a call to -srand()= for each TWiki::User::new() and altering the call to rand() as per suggestions in te Camel-3 book.

When I do a bulk reset most of the passwords are the same.

I still can't see why this is.

True enough, the various calls to rand() occur during the lifetime of one CGI invocation.

Its as if the expression is actually

  return ($password = ($password || int rand(9999))) ;
that is the value from the first call to rand() is being retained.

So I changed it to simply

  return  int rand(9999) ;
but to no avail.

There's something goin on here that I'm not seeing. Can anyone help me out?

-- AntonAylward - 29 Mar 2005

The Fix Is In

OK, I found it.

The Camel-3 book discussed srand() on page 800. It says:

Do not call srand multiple times in your program .... The point of the rnad function is to 'seed' the rand function so it can produce a different sequence each time you run your program. Just do it once at the top of your program or you won't get random numbers out of rand.

The srand() is called in htpasswdGeneratePasswd() to generate the salt when making a new password. The random integer is handed to this function.

Having srand called there was resetting the seed to the same value every time! Well OK, it uses time().... but this was a very, very fast machine. If I'd been debugging on a slow machine I might not have seen this bug!

But that's not the place for it anyway.

It's now in DEVELOP 3938

-- AntonAylward - 30 Mar 2005

Edit | Attach | Watch | Print version | History: r7 < r6 < r5 < r4 < r3 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r7 - 2008-08-24 - TWikiJanitor
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2018 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.