feathersjs-ecosystem / authentication-local

[MOVED] Local authentication plugin for feathers-authentication
https://github.com/feathersjs/feathers
MIT License
26 stars 15 forks source link

why is the password send as plain text instead of encrypting it on client side? #44

Closed nikitpatel24 closed 6 years ago

nikitpatel24 commented 6 years ago

The credentials are sent over the client and the feathers api server are unsecure.


<!DOCTYPE html>
<html>
<head>
  <title>Feathers client</title>
</head>
<body>
<script src="//unpkg.com/feathers-client@^2.0.0/dist/feathers.js"></script>
<script>
  // feathers-client is exposed as the `feathers` global.
  var app = feathers()
    .configure(feathers.hooks())
    .configure(feathers.rest().fetch(fetch))
    .configure(feathers.authentication())

  app.authenticate({
    "strategy": "local",
    "email": "test@example.com",
    "password": "secret"
  }).then(result => {
    console.log('Client authenticated', result);
  });
</script>
</body>
</html>
subodhpareek18 commented 6 years ago

please read the docs https://docs.feathersjs.com/api/authentication/server.html#complete-example

you need to use hooks to add such logic, feathers is very minimal by default

app.service('users').hooks({
  before: {
    find: [
      auth.hooks.authenticate('jwt')
    ],
    create: [
      local.hooks.hashPassword({ passwordField: 'password' })
    ]
  }
});
nikitpatel24 commented 6 years ago

The above creates hash and saves in the database when a user is created. That is correct. But if you print the request data in the before hook. You will find plain text password there.

app.service('authentication').hooks({
    before: {
      // You can chain multiple strategies on create method
      create: [before(), auth.hooks.authenticate(['jwt', 'local'])],
      remove: auth.hooks.authenticate('jwt')
    },
    after: {
      create: [populateUser(config), discard('user.password'), restToSocketAuth()]
    }
  });
function before(options) {
  // The hook function itself is returned.
  return context => {
    console.log(`* ${''}\ntype:${context.type}, method: ${context.method}`);
    if (context.data) {
      console.log('data:', context.data); // the password is recieved as plain text in the server, also during loggin in.
    }
    if (context.params && context.params.query) {
      console.log('query:', context.params.query);
    }

    if (context.result) {
      console.log('result:', context.result);
    }
    if (context.error) {
      console.log('error', context.error);
    }
  };
}
daffl commented 6 years ago

You definitely have to use HTTPS but how is the server supposed to check if the given password matches if you already send it encrypted from the client? I'm sure there is passport strategies that create a hash of the password to send over but this is how local authentication works.