Invalid Passport – The Daily WTF

Date:

Share:

Gretchen wanted to, in development, disable password authentication. Just for a minute, while she was testing things. That’s when she found this approach to handling authentication.

passport.authenticate('local', { session: true }, async (err, user) => {
  if (err) {
    res.send({ success: false, message: 'Error authenticating user.' })
  } else if (!user) {
    User.query()
      .where({ username: req.body.username })
      .first()
      .then(targetUser => {
        if (targetUser) {
          const hash = User.hashPassword(
            targetUser.password_salt,
            req.body.password
          )
          if (hash === targetUser.password_hash) {
            res.send({
              success: false,
              message: 'Incorrect username or password.',
            })
          } else {
            res.send({
              success: false,
              message: 'Incorrect username or password.',
            })
          }
        } else {
          res.send({
            success: false,
            message: 'Incorrect username or password.',
          })
        }
      })
      .catch(err => {
        res.send({ success: false, message: 'Internal server error' })
      })
  } else if (user.firstLogin) {

  }
})(req, res, next);

passport.authenticate invokes its callback after attempting to authenticate. Now, normally, this is called as middleware on a route defined on the webserver- that is to say, you don’t call it from within your application code, but as part of your routing configuration. That’s not the case here, where this blob is inside of a controller.

That’s weird, but let’s just trace through this code. We attempt to authenticate. When the process completes, our callback function executes. If authentication failed, there’s an error, so we’ll send an error message. Then, if the user object isn’t populated, we attempt to look up the user. If we find a user with that user name, we then hash their password and check if the hash matches. If it does, we send an error message. If it doesn’t, we send an error message. If we didn’t find the user, we send an error message. If anything goes wrong, we send an error message.

Wait a second, back up: if the user exists and their password matches, we send an error message?

I’ll let Gretchen explain a bit more:

passport.authenticate returns an error if the authentication failed and a user object, if it succeeded. We check this immediately: if error is set, return an error message. But then, we check if the user does not exist (aka: the authentication failed).

Yes, the reason user would be null is because the authentication failed. So the error would be set. So that entire branch about validating the user won’t happen: either the authentication worked and we know who the user is, or it failed, in which case we’d have an error. There’s no reasonable world where there’s no error but also no user object.

So yes, if authentication failed, but you manually re-run the authentication and it succeeds for some reason, yeah, you probably should still return an error. But I don’t know if it’s “Incorrect username or password”. It probably should be “Invalid reality, please restart the universe and see if the problem persists.”

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!

Source link

Subscribe to our magazine

━ more like this

Crazy New Ideas

May 2021There's one kind of opinion I'd be very afraid to express publicly. If someone I knew to be both a domain expert and a...

Bloomer Shorts Are Trending — Here’s Where to Buy Them

While each product featured is independently selected by our editors, we may include paid promotion. If you buy something through our links, we may...

My, How You’ve Grown!

 Us exactly 1 year ago when Aria was tiny and I held all my secrets in that long hair Disclosure: Post sponsored by RB These last...

What Functional Programmers Get Wrong About Systems

Static types, algebraic data types, making illegal states unrepresentable: the functional programming tradition has developed extraordinary tools for reasoning about programs....

Some happy book news and library love. – The Bloggess

How To Be Okay When Nothing Is Okay got a starred review from Library Journal! (Starred reviews are rare as hen’s teeth and...