New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It fails connection when server uses PAM #438

Open
angiolep opened this Issue Oct 14, 2016 · 11 comments

Comments

Projects
None yet
6 participants
@angiolep

angiolep commented Oct 14, 2016

When I try to connect as a user the server expects to authenticate via the PAM Authentication Plugin, the following error is thrown

Error: Client does not support authentication protocol requested by server;
       consider upgrading MariaDB client

After reading your node-mysql2 docs, and some investigations, I finally realized there's no support for mysql_clear_password capabilities yet. I realized you provided an authSwitchHandler configuration setting to properly react when the server asks for specific authentication methods.

Couldn't it be useful providing mysql_clear_password the same way mysql_native_password authentication capabilities have been already provided internally? After reading the official MySQL Clear Text Authentication piece of documentation, we could easily implement it in Javascript.

@sidorares

This comment has been minimized.

Show comment
Hide comment
@sidorares

sidorares Oct 14, 2016

Owner

I'm a bit on the fence about if we should have clear text authentication bundled in core, as I'd like to discourage it's use. Maybe we should add it as example using initial handshake with mysql_clear_password plugin auth (not possible yet but should be there soon) or as authSwitch handler ( possible right now, I reckon handler function would be less than ~20 lines of js )

Implementation of clear text auth in mysqljs/mysql: https://github.com/mysqljs/mysql/blob/a0f2cec26ee86536dbc1c2837b92b191ca9618f1/lib/protocol/Auth.js#L88-L106 and https://github.com/mysqljs/mysql/blob/c226ee74a14d99a1bf9a3d7a9606c34ffff533e4/lib/protocol/sequences/Handshake.js#L77

Owner

sidorares commented Oct 14, 2016

I'm a bit on the fence about if we should have clear text authentication bundled in core, as I'd like to discourage it's use. Maybe we should add it as example using initial handshake with mysql_clear_password plugin auth (not possible yet but should be there soon) or as authSwitch handler ( possible right now, I reckon handler function would be less than ~20 lines of js )

Implementation of clear text auth in mysqljs/mysql: https://github.com/mysqljs/mysql/blob/a0f2cec26ee86536dbc1c2837b92b191ca9618f1/lib/protocol/Auth.js#L88-L106 and https://github.com/mysqljs/mysql/blob/c226ee74a14d99a1bf9a3d7a9606c34ffff533e4/lib/protocol/sequences/Handshake.js#L77

@sidorares

This comment has been minimized.

Show comment
Hide comment
@sidorares

sidorares Oct 14, 2016

Owner

Couldn't it be useful providing mysql_clear_password the same way mysql_native_password authentication capabilities have been already provided internally?

yes, this is another option, might go this route

Owner

sidorares commented Oct 14, 2016

Couldn't it be useful providing mysql_clear_password the same way mysql_native_password authentication capabilities have been already provided internally?

yes, this is another option, might go this route

@angiolep

This comment has been minimized.

Show comment
Hide comment
@angiolep

angiolep Oct 21, 2016

Despite it seems an unsafe way to send passwords over the network, mysql_clear_password is just one of the MySQL Authentication Methods specified in

https://dev.mysql.com/doc/internals/en/authentication-method.html

and requested in

http://dev.mysql.com/worklog/task/?id=1054

The simplest piece of Javascript I had to write to make mysqlj support it:

dbConf.authSwitchHandler = (data, cb) => {
    if (data.pluginName === 'mysql_clear_password') {
      // https://dev.mysql.com/doc/internals/en/clear-text-authentication.html
      var password = dbConf.password + '\0';
      var buffer = Buffer.from(password);
      cb(null, buffer);
    }
  };

angiolep commented Oct 21, 2016

Despite it seems an unsafe way to send passwords over the network, mysql_clear_password is just one of the MySQL Authentication Methods specified in

https://dev.mysql.com/doc/internals/en/authentication-method.html

and requested in

http://dev.mysql.com/worklog/task/?id=1054

The simplest piece of Javascript I had to write to make mysqlj support it:

dbConf.authSwitchHandler = (data, cb) => {
    if (data.pluginName === 'mysql_clear_password') {
      // https://dev.mysql.com/doc/internals/en/clear-text-authentication.html
      var password = dbConf.password + '\0';
      var buffer = Buffer.from(password);
      cb(null, buffer);
    }
  };

@angiolep angiolep closed this Oct 21, 2016

@angiolep angiolep reopened this Oct 21, 2016

@sidorares

This comment has been minimized.

Show comment
Hide comment
@sidorares

sidorares Oct 22, 2016

Owner

What about this: add support for cleartext auth and "old auth" but by default only allow to use them when connecting over unix socket or to localhost or over ssl

Owner

sidorares commented Oct 22, 2016

What about this: add support for cleartext auth and "old auth" but by default only allow to use them when connecting over unix socket or to localhost or over ssl

@angiolep

This comment has been minimized.

Show comment
Hide comment
@angiolep

angiolep Oct 27, 2016

It seems you're too much concerned of addressing possible MySQL authentication method's vulnerabilities (particularly those you believe could arise from cleartext_authentication)

Shouldn't those vulnerability concerns be addressed by MySQL designers themselves rather than by this node-mysql2 driver? Official MySQL documentation is just listing all the authentication methods a fully-compliant driver-client should be able to support

https://dev.mysql.com/doc/internals/en/authentication-method.html

As many other MySQL drivers do (for other programming languages such as Java, Python, Ruby etc.) shouldn't this node-mysql2 driver for Javascript just support all of the above authentication methods despite their possible vulnerabilities?

Why shall this node-mysql2 deny some authentication methods (though they must be provided) if some conditions are not met (such as denying cleartext_authentication if no SSL/TLS is involved) ? The official MySQL documentation doesn't state that.

You're probably not considering that in certain private networks (such as those for big private corporations) password are simply transmitted clear_text because there are Kerberos Distribution Centers in place to provide security. That's one of the reasons MySQL designers have been running the following task

http://dev.mysql.com/worklog/task/?id=1054

and I suppose there are many other reasons the most recent MySQL servers delegate authentication to an external PAM - Pluggagle Authentication Module. That's why this node-mysql2 should send password in clear text when asked by the server side.

angiolep commented Oct 27, 2016

It seems you're too much concerned of addressing possible MySQL authentication method's vulnerabilities (particularly those you believe could arise from cleartext_authentication)

Shouldn't those vulnerability concerns be addressed by MySQL designers themselves rather than by this node-mysql2 driver? Official MySQL documentation is just listing all the authentication methods a fully-compliant driver-client should be able to support

https://dev.mysql.com/doc/internals/en/authentication-method.html

As many other MySQL drivers do (for other programming languages such as Java, Python, Ruby etc.) shouldn't this node-mysql2 driver for Javascript just support all of the above authentication methods despite their possible vulnerabilities?

Why shall this node-mysql2 deny some authentication methods (though they must be provided) if some conditions are not met (such as denying cleartext_authentication if no SSL/TLS is involved) ? The official MySQL documentation doesn't state that.

You're probably not considering that in certain private networks (such as those for big private corporations) password are simply transmitted clear_text because there are Kerberos Distribution Centers in place to provide security. That's one of the reasons MySQL designers have been running the following task

http://dev.mysql.com/worklog/task/?id=1054

and I suppose there are many other reasons the most recent MySQL servers delegate authentication to an external PAM - Pluggagle Authentication Module. That's why this node-mysql2 should send password in clear text when asked by the server side.

@sidorares

This comment has been minimized.

Show comment
Hide comment
@sidorares

sidorares Oct 27, 2016

Owner

That's why this node-mysql2 should send password in clear text when asked by the server side.

I agree with most of what you say, but I think at API level it should be very clear when credentials are sent securely and when not. Yes, there might be a lot of scenarios when this is not important ( local db, connecting over ssh tunnel etc ). mysqljs/mysql currently only support mysql_native_password and mysql_old_password and insecureAuth flag is required for latter to be used. We probably should be consistent with that.

@dougwilson Do you have an opinion on this ?

Owner

sidorares commented Oct 27, 2016

That's why this node-mysql2 should send password in clear text when asked by the server side.

I agree with most of what you say, but I think at API level it should be very clear when credentials are sent securely and when not. Yes, there might be a lot of scenarios when this is not important ( local db, connecting over ssh tunnel etc ). mysqljs/mysql currently only support mysql_native_password and mysql_old_password and insecureAuth flag is required for latter to be used. We probably should be consistent with that.

@dougwilson Do you have an opinion on this ?

@dougwilson

This comment has been minimized.

Show comment
Hide comment
@dougwilson

dougwilson Oct 27, 2016

Collaborator

I have been silently following this conversation and don't have any strong opinions on it, but I do agree generally that it should be opt-in only. Even MySQL's own documentation shows they also make it opt-in only for their own clients (http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html).

Collaborator

dougwilson commented Oct 27, 2016

I have been silently following this conversation and don't have any strong opinions on it, but I do agree generally that it should be opt-in only. Even MySQL's own documentation shows they also make it opt-in only for their own clients (http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html).

@sidorares

This comment has been minimized.

Show comment
Hide comment
@sidorares

sidorares Oct 28, 2016

Owner

@angiolep I'm happy to bundle mysql_clear_password and mysql_old_auth AuthSwitch handlers and have them called automatically when server request this type of auth, but only if the client explicitly turned on insecureAuth switch. It's not super high priority for me right now - feel free to send PR if you want this to be implemented faster

Owner

sidorares commented Oct 28, 2016

@angiolep I'm happy to bundle mysql_clear_password and mysql_old_auth AuthSwitch handlers and have them called automatically when server request this type of auth, but only if the client explicitly turned on insecureAuth switch. It's not super high priority for me right now - feel free to send PR if you want this to be implemented faster

@nathanewakefield

This comment has been minimized.

Show comment
Hide comment
@nathanewakefield

nathanewakefield Mar 28, 2017

Not sure if this is where I should ask... but does anyone have steps for implementing a solution to the original error?

nathanewakefield commented Mar 28, 2017

Not sure if this is where I should ask... but does anyone have steps for implementing a solution to the original error?

@elephantjim

This comment has been minimized.

Show comment
Hide comment
@elephantjim

elephantjim Jun 3, 2017

FWIW, mysql_clear_password is needed to be able to connect to an Aurora database on AWS RDS when using IAM auth tokens. The connection to the RDS instance is over SSL, and the authentication token is sent in the clear (because it's already an HMAC signature).

@angiolep 's fix in #438 (comment) worked for me. Thanks!

elephantjim commented Jun 3, 2017

FWIW, mysql_clear_password is needed to be able to connect to an Aurora database on AWS RDS when using IAM auth tokens. The connection to the RDS instance is over SSL, and the authentication token is sent in the clear (because it's already an HMAC signature).

@angiolep 's fix in #438 (comment) worked for me. Thanks!

@kennu

This comment has been minimized.

Show comment
Hide comment
@kennu

kennu Oct 27, 2017

I also ran into this problem when trying to connect Sequelize to AWS RDS Aurora using IAM authentication tokens. Too bad the mysql2 driver does not work out of the box. Had to spend time looking how to implement a workaround for Sequelize. I was able to pass the previously given fix like this in the Sequelize constructor options:

dialectOptions: {
  authSwitchHandler: authSwitchHandler,
  ssl: 'Amazon RDS',
},

kennu commented Oct 27, 2017

I also ran into this problem when trying to connect Sequelize to AWS RDS Aurora using IAM authentication tokens. Too bad the mysql2 driver does not work out of the box. Had to spend time looking how to implement a workaround for Sequelize. I was able to pass the previously given fix like this in the Sequelize constructor options:

dialectOptions: {
  authSwitchHandler: authSwitchHandler,
  ssl: 'Amazon RDS',
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment