Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use strong random number/string generators inside generatePassword() #15740

Open
patrickatwsrn opened this issue Jun 17, 2021 · 4 comments · May be fixed by #16521
Open

Use strong random number/string generators inside generatePassword() #15740

patrickatwsrn opened this issue Jun 17, 2021 · 4 comments · May be fixed by #16521
Labels
feature Request about implementing a brand new function or possibility.

Comments

@patrickatwsrn
Copy link

patrickatwsrn commented Jun 17, 2021

Feature request

Summary

Looking for a native solution to create random strings, I stumbled upon the generate Password function today.

I've noticed that the "randomness" of the generated Password relies on mt_rand(), a "Pseudo-Random Number Generator". I guess this is a pice of code that has been active from the old php5 days. PRNG are considered to be a "weak" nowadays.

Basing a random number on a timestamp using srand() is also considered to be a potential problem.

    source: core/model/modx/moduser.class.php, line 797
    /**
     * Returns a randomly generated password
     *
     * @param integer $length The length of the password
     * @param array $options
     * @return string The newly generated password
     */
    public function generatePassword($length = null,array $options = array()) {
        if ($length === null) {
            $length = $this->xpdo->getOption('password_generated_length', null, 10, true);
        }
        $passwordMinimumLength = $this->xpdo->getOption('password_min_length', null, 8, true);
        if ($length < $passwordMinimumLength) {
            $length = $passwordMinimumLength;
        }
        $options = array_merge(array(
            'allowable_characters' => 'abcdefghjkmnpqrstuvxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789',
            'srand_seed_multiplier' => 1000000,
        ),$options);

        $ps_len = strlen($options['allowable_characters']);
        srand((double) microtime() * $options['srand_seed_multiplier']);
        $pass = '';
        for ($i = 0; $i < $length; $i++) {
            $pass .= $options['allowable_characters'][mt_rand(0, $ps_len -1)];
        }
        return $pass;
    }

Why is it needed?

Random passwords should be random by todays standards.

I'm aware that its very unlikely that the login mechanism might be compromised by this "vulnerabilty", but I like to point out that a modx developer might make use of this function to generate a "secure" and "random" strings for other purposes.

Suggested solution(s)

In php 7 "Cryptographically Secure Pseudo-Random NUMBER/STRING Generators" are available. These methods are considered to be "strong":

PHP 5.x polyfill for random_bytes() and random_int()

SIDENOTE:

The random_bytes() function returns a binary string which may contain the \0 character. This can cause trouble in several common scenarios, such as storing this value in a database or including it as part of the URL. The solution is to hash the value returned by random_bytes() with a hashing function such as md5 or sha1.
SOURCE: https://symfony.com/doc/current/components/security/secure_tools.html

Discussion

  • How important are random strings/numbers?
  • Should modx provide them, or should developers create their own methods?
  • Are there more random number/string generators inside the core that should be reviewed?

Cheers patrick

@patrickatwsrn patrickatwsrn added the feature Request about implementing a brand new function or possibility. label Jun 17, 2021
@patrickatwsrn patrickatwsrn changed the title Use strong random number/string generators Password() Use strong random number/string generators inside generatePassword() Jun 17, 2021
@Mark-H
Copy link
Collaborator

Mark-H commented Jun 17, 2021

Unfortunately for MODX 2.x we're still in the old php5 days, but this certainly could and should be improved in 3.x.

I wouldn't go as far as saying this particular code is vulnerable because it's not cryptographically secure random but a good improvement nonetheless.

@tillilab
Copy link
Contributor

tillilab commented Mar 4, 2022

Could it be possible at least to add some special chars in the allowable_characters? I mean here:
$options = array_merge(array( 'allowable_characters' => 'abcdefghjkmnpqrstuvxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789', 'srand_seed_multiplier' => 1000000, ),$options);
I remember that some chars are not allowed by modx, but these seem to work:

~!@#$%^&*_-+=[]|:,.?-

Alessandro

@Ruslan-Aleev
Copy link
Collaborator

It's probably worth creating a field in the "User" section where you can specify valid characters for the password, or a field in "System Settings".

@tillilab
Copy link
Contributor

tillilab commented Mar 4, 2022

yes it would be more scalable, my suggestion was for a quick improve for modx 2, I didn't undestand if it's going to be changed in modx 3,
thanks!

@Mark-H Mark-H linked a pull request Feb 10, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Request about implementing a brand new function or possibility.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants