adonisjs / auth

Official Authentication package for AdonisJS
https://docs.adonisjs.com/guides/auth/introduction
MIT License
192 stars 65 forks source link

Jwt: User is able to create jwt token when uid is equal to false #118

Closed renzosunico closed 6 years ago

renzosunico commented 6 years ago

We have a bug in our app which sets the value of uid to false in each request. Surprisingly, a valid token is given after the request.

We can workaround this by not accepting boolean values in our app.

Sample postman request:

auth

thetutlage commented 6 years ago

From the screenshot, I can see value for field origin is set to false. Where in the code you use this value to generate the token?

renzosunico commented 6 years ago

origin_url is our uid set in the auth config.

We have the following configuration:

  jwt: {
    serializer: 'lucid',
    model: 'App/Models/User',
    scheme: 'jwt',
    uid: 'origin_url',
    password: 'secret_key',
    options: {
      algorithm: 'HS256',
      secret: Env.get('APP_KEY'),
      expiresIn: 60 * 60 * 2 // 2 hours
    }
  }

In our controller:

    const originUrl = request.input('origin_url')
    const secretKey = request.input('secret_key')

      const tokens = await auth
        .withRefreshToken()
        .attempt(originUrl, secretKey)

If originUrl is equal to false, it returns a valid token.

thetutlage commented 6 years ago

Which isn't incorrect.

So origin_url is a field inside the database. The auth module simply queries the field based off the current value.

If your database has a row with the value of false inside it, then the query will be considered successful and hence a token is generated for same.

renzosunico commented 6 years ago

We don't have an origin_url with false value in our database and it only happens when origin_url is boolean false. It doesn't create a valid token when origin_url is set to string false.

thetutlage commented 6 years ago

Okay that's interesting.

Can you share the SQL query created when boolean (false) is used. You can turn on database debugging by setting debug: true inside config/database.js file

renzosunico commented 6 years ago
{ method: 'first',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: [ false, 1 ],
  __knexQueryUid: 'knexqueryUid',
  sql: 'select * from `users` where `origin_url` = ? limit ?' }

{ method: 'insert',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings:
  [ '2018-06-19 14:12:40',
    false,
    1,
    'random-string-49c7-814f-abcdefgh',
    'jwt_refresh_token',
    '2018-06-19 14:12:40' ],
  __knexQueryUid: 'knexqueryUid',
  sql: 'insert into `tokens` (`created_at`, `is_revoked`, `user_id`, `token`, `type`, `updated_at`) values (?, ?, ?, ?, ?, ?)' }

I tried querying select * fromuserswhereorigin_url= false directly to database and it returns all rows if I remove the limit. By default, it will get the first row.

Might be related to this: https://stackoverflow.com/questions/6098875/false-value-in-where-clause-returns-all-rows