Skip to content

Allow passwords to be all numbers#2335

Closed
notbrain wants to merge 1 commit into
strongloop:masterfrom
notbrain:master
Closed

Allow passwords to be all numbers#2335
notbrain wants to merge 1 commit into
strongloop:masterfrom
notbrain:master

Conversation

@notbrain

@notbrain notbrain commented May 11, 2016

Copy link
Copy Markdown

Allow number passwords by converting number to string before hashing.

connect to #2324

Allow number passwords by converting number to string before hashing.
@slnode

slnode commented May 11, 2016

Copy link
Copy Markdown

Can one of the admins verify this patch? To accept patch and trigger a build add comment ".ok\W+to\W+test."

@superkhau

Copy link
Copy Markdown
Contributor

Can you add some tests to verify your changes and prevent regressions in the future?

@superkhau superkhau self-assigned this May 11, 2016
Comment thread common/models/user.js
return;
if (typeof plain === 'number') {
plain = plain.toString();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this check should be removed entirely. What if someone makes a mistake somewhere and plain is of type object? Instead, I think that you should add the check for the number above the check for string.

This could also be cleaned up to one line:

if (typeof plain !== 'string') return;

@reichert621 reichert621 May 13, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably better to take advantage of the validatePassword function instead of just doing an early return... maybe by checking if plain is a string on line 610 below, which allows us to reach the hashPassword function where validatePassword is called:

if (typeof plain === 'string' && plain.indexOf('$2a$') === 0 && plain.length === 60) {
  // ...
} else {
  this.$password = this.constructor.hashPassword(plain);
}

so if plain is of type object, it will get passed along and validated (https://github.com/strongloop/loopback/blob/master/common/models/user.js#L570-L583):

User.hashPassword = function(plain) {
  this.validatePassword(plain);
  // ...
};

User.validatePassword = function(plain) {
  if (typeof plain === 'string' && plain) {
    return true;
  }
  var err =  new Error('Invalid password: ' + plain);
  err.statusCode = 422;
  throw err;
};

at which point it will throw a better error message Invalid password: { pw: 'abc123' }, instead of what we currently get (The User instance is not valid. Details: password can't be blank (value: undefined))

What do you think?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reichert621 I like it. But doesn't that still leave the loophole where all-number passwords are still not converted to strings? Your version will throw the error in that case, but I'm not sure it should be up to the framework to say if they should be allowed or not. 18181818 should be converted to '18181818' at some point, and in such a way that an object would not get converted to a string.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enforcement of at least one non-numeric character is a bug as labelled in #2324. The hashing algorithm requires a string of characters but a number should be coerced to a string and that should be the outcome of this PR.

I just want to be clear that the current behavior is not what is expected.

@notbrain, looking forward to seeing the rest of your changes.

@bajtos

bajtos commented Sep 15, 2016

Copy link
Copy Markdown
Member

There is one thing I don't understand. How is it possible that the password argument is of type number? I think that points to bug in strong remoting that should have been fixed by strongloop/strong-remoting#343.

Before landing this patch, could you @superkhau or @richardpringle please verify that the problem is present in LoopBack 3.0 too?

Here is the test case I am thinking about:

  • request POST /api/users

  • send a digits-only password in the body, e.g.

    {
      "email": "test@example.com", 
      "password": "123"
    }

In LB 2.x, I suspect that strong-remoting converts the password property to a number. In LB 3.x, the value should stays as a string.

@slnode

slnode commented Sep 15, 2016

Copy link
Copy Markdown

Can one of the admins verify this patch?

3 similar comments
@slnode

slnode commented Sep 15, 2016

Copy link
Copy Markdown

Can one of the admins verify this patch?

@slnode

slnode commented Sep 15, 2016

Copy link
Copy Markdown

Can one of the admins verify this patch?

@slnode

slnode commented Sep 15, 2016

Copy link
Copy Markdown

Can one of the admins verify this patch?

@superkhau

Copy link
Copy Markdown
Contributor

There is one thing I don't understand. How is it possible that the password argument is of type number?

Good catch, I believe this is wrong too, we need to make sure strings and only numbers work and coerce the numbers into strings as stated by @bajtos. @richardpringle Can you verify this?

@bajtos

bajtos commented Sep 16, 2016

Copy link
Copy Markdown
Member

Good catch, I believe this is wrong too, we need to make sure strings and only numbers work and coerce the numbers into strings as stated by

No magic please. Number arguments should be rejected, it's the responsibility of the client to correctly encode model property values (send password as strings, not numbers).

@superkhau

superkhau commented Sep 17, 2016

Copy link
Copy Markdown
Contributor

@notbrain Are you still interesting in working on this? Please address the review comments and add some tests to verify your changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants