The issue was created to allow the use of passwords with length > 60. But that problem was fix somewhere in the development of D8 (see #9) and this issue changed to adding tests for that functionality.

Original Issue Summary

Problem

During the site install, I created an admin account with a 256 char random password. The password was generated in Keepass, and copied/pasted into the form. I was able to log in when the install completed, perhaps with the help of the browsers' autocomplete. I created an author account with another long password the same way. I logged in successfully as the author and posted some dummy content.
However, a day later, I am unable to log in to either account. I notice that the maxlength attribute on the password field is 60, and if I remove that attribute and then submit the form, Drupal gives me an error message:

Password cannot be longer than 60 characters but is currently 256 characters long.

Edit: I just noticed that when changing a password, the maxlength of the password fields are 128. However, when logging in, the maxlength is 60.

Proposed resolution

Update the core user module and the new password form(s).

Remaining tasks

Edit a core module and a core template?

User interface changes

Display all of the password criteria, including maximum length and restricted characters, when a user is setting a password.

API changes

Consider setting the max password length to a larger value, 60 seems arbitrary and small. Maybe 1KB or so?

As a workaround, I changed the admin password directly in the database using user_hash_password().
For the record, this install is running in WAMP on Windows 7, and I believe that drush is unavailable.

CommentFileSizeAuthor
#83 interdiff_73_82.txt2.32 KBjoshua1234511
#82 1777270_82.patch3.42 KBjoshua1234511
#82 Screenshot 2022-02-15 at 9.09.09 AM.png18.7 KBjoshua1234511
#82 Screenshot 2022-02-15 at 9.04.21 AM.png52.6 KBjoshua1234511
#73 interdiff_71-73.txt2.09 KBshetpooja04
#73 1777270-73.patch2.32 KBshetpooja04
#71 interdiff_69-71.txt612 bytesshetpooja04
#71 1777270-71.patch2.32 KBshetpooja04
#69 1777270-69.patch2.29 KBAkashKumar07
#69 interdiff_66-69.txt826 bytesAkashKumar07
#66 1777270-65.patch2.29 KBAkashKumar07
#66 interdiff_63-65.txt844 bytesAkashKumar07
#63 1777270-63.patch2.3 KBAkashKumar07
#63 interdiff_60-63.txt1.16 KBAkashKumar07
#60 1777270-60.patch2.26 KBquietone
#60 interdiff-58-60.txt737 bytesquietone
#58 1777270-58a.patch2.26 KBquietone
#58 interdiff-58-58a.txt760 bytesquietone
#57 1777270-58.patch2.48 KBquietone
#55 1777270-55.patch1.74 KBquietone
#46 write_tests_for_users-1777270-46.patch7.75 KBZeiP
#43 interdiff-23-37.txt16.83 KBquietone
#37 write_tests_for_users-1777270-37.patch8.9 KBdermario
#36 write_tests_for_users-1777270-36.patch10.84 KBdermario
#33 remove-login-block-password-maxlength-1777270-33.patch370 bytessmokris
#24 UserLoginTest_refactored_1777270_23.patch8.6 KBaries
#22 UserLoginTest_refactored_1777270_22.patch6.71 KBaries
#20 testPasswordLength.patch1.73 KBaries
#17 testPasswordLength.patch1.68 KBaries
#16 testPasswordLength.patch1.68 KBaries
#10 remove-login-block-password-maxlength-1777270-10.patch377 bytesDevin Carlson
#7 remove-login-block-password-maxlength-1777270-7.patch395 bytesDevin Carlson
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

danjro’s picture

I found one of the problems.

On line 1310 of modules/user/user.module:

  $form['pass'] = array('#type' => 'password',
    '#title' => t('Password'),
    '#maxlength' => 60,
    '#size' => 15,
    '#required' => TRUE,
  );

should probably be

  $form['pass'] = array('#type' => 'password',
    '#title' => t('Password'),
    '#maxlength' => 128,
    '#size' => 15,
    '#required' => TRUE,
  );

in order to match line 380 of modules/system/system.module:

  $types['password'] = array(
    '#input' => TRUE,
    '#size' => 60,
    '#maxlength' => 128,
    '#process' => array('ajax_process_form'),
    '#theme' => 'password',
    '#theme_wrappers' => array('form_element'),
  );

Or maybe one of these values should refer to the other, I'm new here.

danjro’s picture

Title: I am no longer able to log in to any of the user accounts that I created with long random passwords. » Maximum password length is 60 chars in user.module and 128 chars in system.module.
danjro’s picture

Assigned: Unassigned » danjro

I would like to learn how to fix this myself, properly, so I am assigning this to myself. However, this will be my first patch, and it may take me a day to figure it all out. I will ask for help on the #drupal irc channel if I need it. If someone beats me to the punch, that's totally cool too.

Devin Carlson’s picture

Version: 7.15 » 8.x-dev

Awesome ross9885, the more core developers the merrier!

Some notes from my inital look at the issue (repeating some of your observations):

  • User module stores passwords in the "pass" column which has a length limit of 128 characters. (user.install)
  • User module provides a block which allows users to enter their username and password in order to login. The block's password textfield has a maximum length restriction of 60 characters. This is incorrect and should be changed to 128. (user.module)
  • When installing Drupal, the password field has no validation check for the length of the password. #1344552: Password confirm field type should have support for #maxlength attribute is related but can be worked around by manually validating the length of the password in install_configure_form_validate() (install.core.inc)
  • When updating a user password on the user edit page, the password field has no validation check for the length of the password. #1344552: Password confirm field type should have support for #maxlength attribute is related but can be worked around by manually validating the length of the password in user_validate_current_pass() (user.module) which is called by AccountFormController (AccountFormController.php)

Also, patches are made against Drupal 8 and then backported to Drupal 7 in order to prevent regressions.

tim.plunkett’s picture

Priority: Major » Normal
Issue tags: +Needs backport to D7

This is a nasty bug, but I don't think it should be blocking other development.

Really nice find, @ross9885! And great issue summary.

ssm2017 Binder’s picture

why not remove the size and maxlength because they are already defined in the default password form element declaration ?

this is ok to define a custom value for custom modules but i think that drupal should have the same value everywhere.

i m telling this because i'm building a custom module and i have overrided the form element maxlenght but this is still forced in some drupal's forms like the login form so i need to also use a form alter or preprocess instead of just altering the default form element.

Devin Carlson’s picture

Assigned: danjro » Devin Carlson
Status: Active » Needs review
Issue tags: +Novice
FileSize
395 bytes

A patch to implement ssm2017 Binder's suggestion.

The login block's password form item doesn't need to declare a maxlength since all password elements have an appropriate default maxlength of 128.

caelon’s picture

Status: Needs review » Reviewed & tested by the community

I have tested the patch and confirmed that it does not enforce 60 characters max on the login form.

Because this pointed out a larger problem that all password fields should be consistent, I did a grep to find all '#type' => 'password' instances assuming they would be the only ones that would have max sizes:

grep -r "'#type' => 'password'" *

I reviewed all nine core files found by that grep and none of them, post-patch, has a maxlength attribute so all are now consistently coded.

webchick’s picture

Version: 8.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Looks like this already got committed at some point down the line to 8.x. Moving down to 7.x, which should have that same test by caelon in #8 to ensure that there's only one instance.

Devin Carlson’s picture

Status: Patch (to be ported) » Needs review
FileSize
377 bytes

The patch from #1772584: Get rid of user_login_block() & user_login() in favour of user_login_form() fixed the issue and was committed three days ago by yourself. :P

See http://drupalcode.org/project/drupal.git/commit/b38996475dd09e5c3709397c...

A patch against D7, since the issue which fixed this in D8 will not be backported.

barraponto’s picture

Status: Needs review » Reviewed & tested by the community

Just ran ack --type-add php=.inc password -A 10 . --php | grep maxlength to doublecheck if we were missing anything, seems ok.

David_Rothstein’s picture

Looks good to me, but shouldn't we have an automated test here too?

This issue has the "Novice" tag, and it might actually be a good test for someone who is looking to get started with simpletests to work on. Basically, the goal would be to create a user with a password equal to the maximum allowed length and then make sure that user can log in (via both the user login block and the regular /user/login page) without any errors.

This test could go into Drupal 8 too, actually...

David_Rothstein’s picture

Title: Maximum password length is 60 chars in user.module and 128 chars in system.module. » Write tests for: Users with passwords over 60 characters cannot log in via the user login block
Version: 7.x-dev » 8.x-dev
Category: bug » task
Status: Reviewed & tested by the community » Active
Issue tags: +Needs tests

Actually, come to think of it, since this is already fixed in Drupal 8 it will be a lot simpler if we just commit it to Drupal 7 now and do the tests as a followup.

So... committed to 7.x - thanks! http://drupalcode.org/project/drupal.git/commit/dafe7ae

David_Rothstein’s picture

Component: user system » user.module

@Devin Carlson, feel free to unassign yourself if you don't want to write those tests, by the way :)

nagwani’s picture

@David Carlson, anything I can help with. Happy to help. Thanks

aries’s picture

FileSize
1.68 KB

Here is patch for the test case.

aries’s picture

FileSize
1.68 KB

I've left a mistake, the length of the valid and invalid case were the same. Apologies.

David_Rothstein’s picture

Status: Active » Needs review

Thanks! Setting to "needs review" so that the testbot will run it.

balintk’s picture

+++ b/core/modules/user/lib/Drupal/user/Tests/UserLoginTest.phpundefined
@@ -23,6 +23,45 @@ public static function getInfo() {
+      if ($password_length === 128) {
+        $this->assertNoText(t('User login'), 'Logged in with 127 character length password.');

Why does the assertion message say 127 characters here when the password was generated with 128 characters?

+++ b/core/modules/user/lib/Drupal/user/Tests/UserLoginTest.phpundefined
@@ -23,6 +23,45 @@ public static function getInfo() {
+      if ($password_length === 129) {
+        $this->assertText(t('Log in'), 'Couldn\'t log in with 255 character long password.');

Similarly, I don't understand the assertion message. Why does it contain 255 characters? I could totally miss something here with those characters, but if that's the case maybe documenting the reason in a comment would be a good idea.
Also, it's just a small thing, but using single quotes and an escaped apostrophe in the string should be avoided (even though this is not inside of t()). I did a quick grep and I learned that it's more common to avoid this situation by using the non-shortened form "could not". Additionally, a super-minor remark: I would also make sure that the two assertion messages have nearly the same wording (i.e.: "length" vs. "long").

aries’s picture

Assigned: Devin Carlson » aries
FileSize
1.73 KB

Thanks Bálint, I've accidentally left those numbers in. I've updated the test according your recommendations.

balintk’s picture

I was focusing on those assertion messages, but now I've given more thoughts to the approach of the patch.

Use assertFailedLogin()

There is already a method in the same class for making an unsuccessful login attempt, it would be better to use that.

Consider implementing setUp() method

Since almost all methods in this class need at least one user account to perform tests it would be interesting to consider implementing the setUp() method, creating user accounts there and making them accessible via class properties so that each test method in the class can utilize them.
One of the user accounts could be created with the maximum allowed numbers of characters in the password (other tests will pass just fine), so in the test method introduced by the patch this password could be simply changed when we want to test the login failure scenario.
If the setUp() method is a good idea, maybe refactoring the other methods to use the user object created by that could be a follow-up issue.

Test user login block as well

As @David_Rothstein said the test should cover the login attempts from a login block as well, not only logins from the regular user login page.

aries’s picture

Cheers Bálint for the review. This patch contains number of improvements what Bálint suggested:

  • UserLoginTest class refactored to use shared user accounts
  • additional test to cover the login block cases

Use of assertFailedLogin(). assertFailedLogin() expects wrong user credentials, where Drupal returns with Sorry, unrecognized username or password. Have you forgotten your password?' instead of Password cannot be longer than... which means the credentials were correct but the password has invalid length. That's why I handled this in different way.

Status: Needs review » Needs work

The last submitted patch, UserLoginTest_refactored_1777270_22.patch, failed testing.

aries’s picture

Now only I fail left which looks like because a bug in the Blocks module. The testPasswordLengthBlock() should be fine, but the issue is a bit weird.

The login fails because the invalid password length, but in the block header instead t('User login') I get the username. With same block the error message and the form appears as it should. Check the raw response here: http://pastebin.com/97nAzeqW . With cURL the login via the UI works fine.

aries’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, UserLoginTest_refactored_1777270_23.patch, failed testing.

smiletrl’s picture

I'm a little confused that have we committed the code to fix the problem described here?
If the answere is yes, so what we need to do now is to write tests for this scenario?

aries’s picture

@smiletrl: I noticed the issue I described in #21 while I was writing tests for log in. I need confirmation, is this a real issue?
To replicate it all you need is to apply the patch I attached and run the test via either Drush (drush test-run UserLoginTest) or UI.

smiletrl’s picture

@aries, yeah, this is an interesting problem as in #24. I get the same issue too.

I suggest do this test manually. Create such user in code directly and login via UI. I agree that there could be some problem with user-login form. Or I'm thinking because the length has been designed in db for 128, this new created user in code could lead to unexpected result from db.

      'pass' => array(
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
        'default' => '',
        'description' => "User's password (hashed).",
      ),

Maybe we could change the way we are testing? Try to create a user with 129 length pass, and get some error? But this page test returns right result:(

Maybe there's problem with drupalPost, like what you assumed. Anyway, let's test this manually, and see what happens:)

aries’s picture

@smiletrl: I've tested manually, I saved and put the response to pastebin.com. The link is in #24.

smiletrl’s picture

a)

John@JOHN-PC /d/apache/drupal82 (user_login_tests-1777270-29)
$ grep -r 'Password cannot be longer' *   

returns nothing. I'm not sure where does this scentence come from.

b) my manual test returns 'Sorry, unrecognized username or password. Have you forgotten your password?' when I try to log in with 129 length password.

c)I think we could add something like this in user.module

/**
 * Maximum length of user password text field.
 */
const USERPASS_MAX_LENGTH = 128;

and do this for user_login_form and user_register_form

  $form['pass'] = array(
    '#type' => 'password',
    '#title' => t('Password'),
    '#size' => 60,
    '#maxlength' => USERPASS_MAX_LENGTH,  // add constraint here.
    '#description' => t('Enter the password that accompanies your username.'),
    '#required' => TRUE,
  );

This should solve our problem.
We may add some password validate process, like username does

  if (drupal_strlen($name) > USERNAME_MAX_LENGTH) {
    return t('The username %name is too long: it must be %max characters or less.', array('%name' => $name, '%max' => USERNAME_MAX_LENGTH));
  }

But this validate looks redundant to me, since $form['name'] ['#maxlength'] has already defined the max length.

d) I think we need so something like this to place user_login_block.

    // Add user login block.
    $this->adminUser = $this->drupalCreateUser(array('administer blocks'));
    $this->drupalLogin($this->adminUser);
    $this->drupalPlaceBlock('user_login_block');
    $this->drupalLogout($this->adminUser);

But it seems this block is there without such an admin-user. Anyway, just a suggestion.

e) I can't explain why this test returns this wierd result. Perhaps it needs deep exploring code effort:(

aries’s picture

@smiletrl: your suggestions are already implemented.

aries’s picture

Issue summary: View changes

Added info about maxlength attribute.

smokris’s picture

Title: Write tests for: Users with passwords over 60 characters cannot log in via the user login block » Users with passwords over 60 characters cannot log in via the user login block
Version: 8.x-dev » 6.x-dev
Issue summary: View changes
Status: Needs work » Needs review
FileSize
370 bytes

This issue also affects Drupal 6.x (and is becoming more noticeable as more of our users are adopting xkcd-style password novellas).

Could we apply the attached backport to Drupal 6.x, then resume work on tests for 8.x?

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.

David_Rothstein’s picture

Title: Users with passwords over 60 characters cannot log in via the user login block » Write tests for: Users with passwords over 60 characters cannot log in via the user login block
Version: 6.x-dev » 8.0.x-dev
Status: Closed (outdated) » Needs work

There are still Drupal 8 patches to review above which add automated tests for this.

dermario’s picture

I took the patch from aries in #24 and refactored it a little to make the tests pass against the latest HEAD. Any improvement suggestions are welcome.

dermario’s picture

Ooops ... sorry something went wrong with my last patch. Please review this one.

dermario’s picture

Status: Needs work » Needs review

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

nicrodgers’s picture

@aries are you still working on this, or can it be unassigned?

mparker17’s picture

Assigned: aries » Unassigned

Going to assume yes, at least in part because it's been 3 years since @aries worked on it and 3 months since the last patch by @dermario. Plus, it looks like it might be good for someone to review at the Drupal North 2016 code sprint tomorrow.

@aries or @dermario, if you are still working on this, please re-assign it to yourself!

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

quietone’s picture

FileSize
16.83 KB

Patch applies to 8.2.x and tests pass, assertion messages are fine.

Added interdiff between the latest two patches, #24 and #37. And retesting latest patch with 8.2.x.

quietone’s picture

Issue summary: View changes

Reviewed the patch in #37. All looks good, at least to me, but I don't know if the changes made in response to #21 are out of scope. Otherwise, I'd RTBC. Anyone care to comment?

Added a summary to the IS.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ZeiP’s picture

I re-rolled the patch against 8.3.x. Additionally I changed the last assert calls on both testGlobalLoginFloodControl() and testPerUserLoginFloodControl() to use a valid user, not the invalid one, since that's what the code originally does and it seems to have been changed in error in patch #37.

naveenvalecha’s picture

Issue tags: -Needs tests, -Novice

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ZeiP’s picture

I ran the tests again against 8.4.x, and it still seems to apply. Hopefully someone finds time to review this.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

borisson_’s picture

Status: Needs review » Needs work

I found a couple of things in this patch that should be updated to our new standards. I like the idea of the additional coverage!

  1. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -13,6 +13,49 @@
    +   * Modules to enable.
    +   *
    +   * @var array
    

    Should be {@inheritdoc}

  2. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -13,6 +13,49 @@
    +  public static $modules = array('block');
    

    Short array syntax should be used instead.

  3. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -13,6 +13,49 @@
    +   * @var array
    

    This is an array of users, @var \Drupal\user\UserInterface[]

  4. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -13,6 +13,49 @@
    +    $password_lengths = array(
    

    ^

  5. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -13,6 +13,49 @@
    +      $account = entity_create('user', array(
    +        'name' => $test_name,
    +        'mail' => $test_name . '@example.com',
    +        'pass' => $test_pass,
    +        'status' => 1,
    +      ));
    +      $account->save();
    

    We shouldn't use entity_create here, we can use the createUser method and pass just the pass to it. That should be sufficient for this.

  6. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -29,6 +72,62 @@ public function testLoginCacheTagsAndDestination() {
    +    /** @var User $user_with_valid_password_length */
    

    This line can be removed, if we correctly document the $this->userCases parameter.

  7. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -29,6 +72,62 @@ public function testLoginCacheTagsAndDestination() {
    +    $auth = array(
    

    Should be short array syntax.

  8. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -29,6 +72,62 @@ public function testLoginCacheTagsAndDestination() {
    +    $this->drupalPostForm('user/login', $auth, t('Log in'));
    +    $this->assertNoText(t('User login'), 'Logged in with 128 character long password.');
    +    $this->assertPattern('!<h4.*?' . t('Member for') . '.*?</h4>!', 'Redirected to /user');
    

    No need for the t here, as this page is not translated.

  9. +++ b/core/modules/user/src/Tests/UserLoginTest.php
    @@ -29,6 +72,62 @@ public function testLoginCacheTagsAndDestination() {
    +    /** @var User $user_with_invalid_password_length */
    

    ^

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

quietone’s picture

Version: 8.8.x-dev » 9.1.x-dev
Issue tags: +Needs reroll, +Bug Smash Initiative

As part of the Bug smash initiative, we are triaging issues that are marked 'Postponed (maintainer needs more info)'. I started with the referenced issue, #2851784: Long passwords allowed when creating account, but logging in fails and continued on to here.

The tests in the latest patch here specifically test long passwords in the user form and in the user login block. There are are also changes to testLoginCacheTagsAndDestination() and testGlobalLoginFloodControl() but these are variable name changes and do not alter the functionality of those tests. Tests of long passwords were added to core in #2378703: Port denial of service fixes from SA-CORE-2014-006 to Drupal 8 in \Drupal\Tests\Core\Password\PasswordHashingTest and there is a test of user login, \Drupal\Tests\user\Functional\UserLoginTest but that doesn't specifically test long passwords and there isn't a test of logging in from the user login block. So, I reckon the work to do here is to add functional tests for logging in on the user page and via the user login block that specifically test long passwords.

quietone’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
1.74 KB

Following on I added a test to UserLoginTest to test the use of long passwords, using PasswordInterface::PASSWORD_MAX_LENGTH for the length, which is 512. Unfortunately the test fails and looking at the html output it reports
Password: may not be longer than 255 characters.

Curious I ran some more tests and found that only passwords with length of < 128 will pass. And further the error message displayed changes depending on the length of the password.

129: Password cannot be longer than 128 characters but is currently 129 characters long.
254: Password cannot be longer than 128 characters but is currently 254 characters long.
512: Password: may not be longer than 255 characters.

Then I went back to review the manual testing I did earlier. I created a password of 521 characters and entered that at user/1/edit and it saved successfully and I could login with that password. I logged out and removed characters from the end of the password to make the password 511 characters long. I could successfully login with that as well. Further testing and found that the max length in 127. At least that agrees with testing results.

The next steps are to understand why the password length is 127 despite what PassowrdInterface states and why the test produces error messages not seen during manual testing (standard profile).

Status: Needs review » Needs work

The last submitted patch, 55: 1777270-55.patch, failed testing. View results

quietone’s picture

Status: Needs work » Needs review
FileSize
2.48 KB

Spoke with larowlan on #bugsmash who lead me to \Drupal\Core\Render\Element\Password::getInfo where the field length is set to 128.

so looking at PasswordItem it extends StringItem
StringItem has a max_length of 255 but that’s for binary => FALSE
passwords are case-sensitive so they have binary=> TRUE
StringItem defaults to “VARCHAR”
nothing in the mysql docs tells me binary has any bearing on the max length
\Drupal\Core\Field\Plugin\Field\FieldType\StringItem::getConstraints is where the message should be coming from
but that would surely be 255
not sure if any of this is useful
so digging deeper
User forms are built with AccountForm
The password field is #type password_confirm
which is PasswordConfirm render element
it has a process callback which adds two fields of #type password
and there we find the culprit (edited) 
\Drupal\Core\Render\Element\Password::getInfo
defaults to max length 128
@quietone ^ stream of consciousness to find what’s going on here
so posting via Rest etc, you could create a password up to 255 (enforced by the data layer)
but via the UI, the max is 128 (enforced by the render element defaults)

So, I have updated the test to verify that passwords of length 128 pass but 129 fail. The IS refers to the login block, but that just uses the accountform anyway, so all should be good here. I don't think an interdiff is needed here.

I intend to make a followup to change the length to 255.

quietone’s picture

Darn, coding standard errors. And I named the patch in comment #57 with '58' instead of '57. Therefor the new patch is name '58a', couldn't think of a better option right now.

larowlan’s picture

+++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
@@ -154,6 +154,58 @@ public function testPasswordRehashOnLogin() {
+    $session->pageTextNotContains('Password cannot be longer than.');

is the . here giving false positives?

quietone’s picture

Yes, it was giving false positives. Fixed now.

longwave’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
    @@ -152,6 +152,58 @@ public function testPasswordRehashOnLogin() {
    +    // \Drupal\Core\Render\Element\Password::getInfo.
    

    getInfo should end with ().

  2. +++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
    @@ -152,6 +152,58 @@ public function testPasswordRehashOnLogin() {
    +    $session->pageTextContains('Password cannot be longer than 128 characters but is currently 129 characters long.');
    

    Should we just inject $length and $length + 1 in the string, so when we update $length in the future we only have to do it in one place?

AkashKumar07’s picture

Assigned: Unassigned » AkashKumar07
AkashKumar07’s picture

Status: Needs work » Needs review
FileSize
1.16 KB
2.3 KB

Made suggested changes. Please review.

longwave’s picture

  1. +++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
    @@ -152,6 +152,58 @@ public function testPasswordRehashOnLogin() {
    +    $session = $this->assertSession();
    

    Usually we don't extract the session to a variable and always call assertSession() each time, sorry for not spotting this before.

  2. +++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
    @@ -152,6 +152,58 @@ public function testPasswordRehashOnLogin() {
    +    $session->pageTextContains('Password cannot be longer than @from characters but is currently @to characters long.', ['@from' => $count, '@to' => $count+1]);
    

    This won't work, you just need to put $length and $length + 1 directly into the string.

Status: Needs review » Needs work

The last submitted patch, 63: 1777270-63.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

AkashKumar07’s picture

AkashKumar07’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 66: 1777270-65.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

AkashKumar07’s picture

Status: Needs work » Needs review
FileSize
826 bytes
2.29 KB

Status: Needs review » Needs work

The last submitted patch, 69: 1777270-69.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

shetpooja04’s picture

Status: Needs work » Needs review
FileSize
2.32 KB
612 bytes
longwave’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
    @@ -152,6 +152,58 @@ public function testPasswordRehashOnLogin() {
    +    $session = $this->assertSession();
    ...
    +    $session->pageTextNotContains('Password cannot be longer than');
    +    $session->pageTextContains('Member for');
    

    I still think we don't need a separate variable for $session, we usually just call $this->assertSession()->... each time.

  2. +++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
    @@ -152,6 +152,58 @@ public function testPasswordRehashOnLogin() {
    +    $session->pageTextContains('Password cannot be longer than '. $length .' characters but is currently '. ($length+1) .' characters long.');
    

    There are some coding standards issues on this line, . and + operators need spaces either side.

shetpooja04’s picture

Status: Needs work » Needs review
FileSize
2.32 KB
2.09 KB

Added changes and applied patch according to the comment in #72
Please review

samiullah’s picture

Patch is applying correctly.
If code review is fine, this could be moved to RTBCa

Status: Needs review » Needs work

The last submitted patch, 73: 1777270-73.patch, failed testing. View results

shetpooja04’s picture

Status: Needs work » Needs review

It was a random test failure, setting it to needs review

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Kristen Pol’s picture

Assigned: AkashKumar07 » Unassigned
Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
Issue tags: +ContributionWeekend2022

Thanks for the updated patch. I've reviewed the issue summary, patch, and recent comments. Based on the following, I'm marking RTBC.

1. Patch handles the issue noted in the issue summary and nothing else.

2. Code is clear and has been updated to address the most recent comments in #72.

3. Patch applies cleanly to 9.3.x and 9.4.x branches.

4. Test passes.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
@@ -152,6 +152,56 @@ public function testPasswordRehashOnLogin() {
+  public function doPasswordLengthLogin($account, $current_password, $length) {

This method could do with some typehints and return typehints and docs.

Also I'm pretty sure the test is using deprecated methods. I.e drupalPostForm()

+++ b/core/modules/user/tests/src/Functional/UserLoginTest.php
@@ -152,6 +152,56 @@ public function testPasswordRehashOnLogin() {
+    $this->assertSession()->responseContains('The changes have been saved.');

I think this should use pageTextContains().

joshua1234511’s picture

Tested the patch from #73 does not apply with 9.4.x-dev.
Patch does not apply

Updated the patch to work with 9.4.x-dev
Replaced the deprecated functions and added type hints to functions.

Test Runs

joshua1234511’s picture

FileSize
2.32 KB

Missed adding the Interdiff

Kristen Pol’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for the updated patch. Back to RTBC based on:

1. Reviewed the interdiff for the feedback from #81 and everything appears to be addressed along with adding documentation and fixing coding standards.

2. Patch applies cleanly to 9.3.x (with fuzz) and 9.4.x branches.

3. Test passes.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 34bccfc8138 to 10.0.x and a0ffc4bba21 to 9.4.x. Thanks!

Drupal 7 backports require there own issues as per policy now.

  • alexpott committed 34bccfc on 10.0.x
    Issue #1777270 by aries, quietone, AkashKumar07, shetpooja04, Devin...

  • alexpott committed a0ffc4b on 9.4.x
    Issue #1777270 by aries, quietone, AkashKumar07, shetpooja04, Devin...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.