Skip to content

Commit d06a41a

Browse files
committed
Ensure that mysql_clear_password is never used over insecure connections.
1 parent 150e5ef commit d06a41a

File tree

5 files changed

+59
-8
lines changed

5 files changed

+59
-8
lines changed

lib/protocol/Auth.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ var Buffer = require('safe-buffer').Buffer;
22
var Crypto = require('crypto');
33
var Auth = exports;
44

5-
function auth(name, data, options) {
5+
function auth(name, data, options, isSecure) {
66
options = options || {};
77

88
switch (name) {
99
case 'mysql_native_password':
1010
return Auth.token(options.password, data.slice(0, 20));
1111
case 'mysql_clear_password':
12-
return Buffer.from(options.password);
12+
if (!isSecure) {
13+
throw new Error('Authentication method mysql_clear_password not supported on insecure connections');
14+
} else {
15+
return Buffer.from(options.password);
16+
}
1317
default:
1418
return undefined;
1519
}

lib/protocol/sequences/Handshake.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,21 @@ Handshake.prototype.determinePacket = function determinePacket(firstByte, parser
3535

3636
Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) {
3737
var name = packet.authMethodName;
38-
var data = Auth.auth(name, packet.authMethodData, {
39-
password: this._config.password
40-
});
38+
var data, error;
39+
try {
40+
data = Auth.auth(name, packet.authMethodData, {
41+
password: this._config.password
42+
}, this._tls);
43+
} catch (e) {
44+
error = e;
45+
}
4146

4247
if (data !== undefined) {
4348
this.emit('packet', new Packets.AuthSwitchResponsePacket({
4449
data: data
4550
}));
4651
} else {
47-
var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
52+
var err = error || new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
4853
err.code = 'UNSUPPORTED_AUTH_METHOD';
4954
err.fatal = true;
5055
this.end(err);
@@ -82,6 +87,7 @@ Handshake.prototype['HandshakeInitializationPacket'] = function(packet) {
8287
};
8388

8489
Handshake.prototype._tlsUpgradeCompleteHandler = function() {
90+
this._tls = true;
8591
this._sendCredentials();
8692
};
8793

test/FakeServer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ FakeConnection.prototype.handshake = function(options) {
9595
var packetOptions = common.extend({
9696
scrambleBuff1 : Buffer.from('1020304050607080', 'hex'),
9797
scrambleBuff2 : Buffer.from('0102030405060708090A0B0C', 'hex'),
98-
serverCapabilities1 : 512, // only 1 flag, PROTOCOL_41
98+
serverCapabilities1 : 512 | 1 << 11, // only 2 flags, PROTOCOL_41 and SSL
9999
protocol41 : true
100100
}, this._handshakeOptions);
101101

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
var assert = require('assert');
2+
var common = require('../../common');
3+
var connection = common.createConnection({
4+
port : common.fakeServerPort,
5+
password : 'authswitch'
6+
});
7+
8+
var server = common.createFakeServer();
9+
10+
var error;
11+
server.listen(common.fakeServerPort, function (err) {
12+
assert.ifError(err);
13+
14+
connection.connect(function (err) {
15+
error = err;
16+
connection.destroy();
17+
server.destroy();
18+
});
19+
});
20+
21+
server.on('connection', function(incomingConnection) {
22+
incomingConnection.on('authSwitchResponse', function (packet) {
23+
this._sendAuthResponse(packet.data, Buffer.from('authswitch'));
24+
});
25+
26+
incomingConnection.on('clientAuthentication', function () {
27+
this.authSwitchRequest({
28+
authMethodName : 'mysql_clear_password',
29+
authMethodData : Buffer.alloc(0)
30+
});
31+
});
32+
33+
incomingConnection.handshake();
34+
});
35+
36+
process.on('exit', function() {
37+
assert.equal(error.message, 'Authentication method mysql_clear_password not supported on insecure connections');
38+
});

test/unit/connection/test-auth-switch-clear.js renamed to test/unit/connection/test-auth-switch-clear-secure.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ var assert = require('assert');
22
var common = require('../../common');
33
var connection = common.createConnection({
44
port : common.fakeServerPort,
5-
password : 'authswitch'
5+
password : 'authswitch',
6+
ssl : {
7+
rejectUnauthorized: false
8+
}
69
});
710

811
var server = common.createFakeServer();

0 commit comments

Comments
 (0)