From 9ff781d10d9d51b7a023350b839844a386622969 Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Wed, 10 May 2017 07:14:09 -0400 Subject: [PATCH 1/3] Fix escaping of libpq connection string properties Fix handlings of libpq connection properties to properly escape single quotes and backslashes. Previously the values were surrounded in single quotes which handled whitespace within the property value, but internal single quotes and backslashes would cause invalid connection strings to be generated. --- lib/connection-parameters.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/connection-parameters.js b/lib/connection-parameters.js index c1c535e98..da0e998d9 100644 --- a/lib/connection-parameters.js +++ b/lib/connection-parameters.js @@ -65,10 +65,15 @@ var ConnectionParameters = function(config) { this.fallback_application_name = val('fallback_application_name', config, false); }; +// Convert arg to a string, surround in single quotes, and escape single quotes and backslashes +var quoteParamValue = function(value) { + return "'" + ('' + value).replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'"; +}; + var add = function(params, config, paramName) { var value = config[paramName]; if(value) { - params.push(paramName+"='"+value+"'"); + params.push(paramName + "=" + quoteParamValue(value)); } }; @@ -87,23 +92,23 @@ ConnectionParameters.prototype.getLibpqConnectionString = function(cb) { add(params, ssl, 'sslcert'); if(this.database) { - params.push("dbname='" + this.database + "'"); + params.push("dbname=" + quoteParamValue(this.database)); } if(this.replication) { - params.push("replication='" + this.replication + "'"); + params.push("replication=" + quoteParamValue(this.replication)); } if(this.host) { - params.push("host=" + this.host); + params.push("host=" + quoteParamValue(this.host)); } if(this.isDomainSocket) { return cb(null, params.join(' ')); } if(this.client_encoding) { - params.push("client_encoding='" + this.client_encoding + "'"); + params.push("client_encoding=" + quoteParamValue(this.client_encoding)); } dns.lookup(this.host, function(err, address) { if(err) return cb(err, null); - params.push("hostaddr=" + address); + params.push("hostaddr=" + quoteParamValue(address)); return cb(null, params.join(' ')); }); }; From fe75025d113a63b4c42494983083ed7dc3bf1015 Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Wed, 10 May 2017 09:07:54 -0400 Subject: [PATCH 2/3] Update expected output in test to be quoted Update the expect host output in the connection parameter test to expect it to be surrounded by single quotes. --- test/unit/connection-parameters/creation-tests.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/connection-parameters/creation-tests.js b/test/unit/connection-parameters/creation-tests.js index 33ee7eeeb..25729c7a7 100644 --- a/test/unit/connection-parameters/creation-tests.js +++ b/test/unit/connection-parameters/creation-tests.js @@ -126,7 +126,7 @@ test('libpq connection string building', function() { checkForPart(parts, "user='brian'"); checkForPart(parts, "password='xyz'"); checkForPart(parts, "port='888'"); - checkForPart(parts, "hostaddr=127.0.0.1"); + checkForPart(parts, "hostaddr='127.0.0.1'"); checkForPart(parts, "dbname='bam'"); })); }); @@ -143,7 +143,7 @@ test('libpq connection string building', function() { assert.isNull(err); var parts = constring.split(" "); checkForPart(parts, "user='brian'"); - checkForPart(parts, "hostaddr=127.0.0.1"); + checkForPart(parts, "hostaddr='127.0.0.1'"); })); }); @@ -173,7 +173,7 @@ test('libpq connection string building', function() { assert.isNull(err); var parts = constring.split(" "); checkForPart(parts, "user='brian'"); - checkForPart(parts, "host=/tmp/"); + checkForPart(parts, "host='/tmp/'"); })); }); From 95779ace7d13c65ce8bdbc8d5e8ea299bd0581f9 Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Wed, 10 May 2017 09:08:32 -0400 Subject: [PATCH 3/3] Add test for configs with quotes and backslashes --- .../unit/connection-parameters/creation-tests.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/unit/connection-parameters/creation-tests.js b/test/unit/connection-parameters/creation-tests.js index 25729c7a7..85c2bd037 100644 --- a/test/unit/connection-parameters/creation-tests.js +++ b/test/unit/connection-parameters/creation-tests.js @@ -177,6 +177,22 @@ test('libpq connection string building', function() { })); }); + test('config contains quotes and backslashes', function() { + var config = { + user: 'not\\brian', + password: 'bad\'chars', + port: 5432, + host: '/tmp/' + }; + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='not\\\\brian'"); + checkForPart(parts, "password='bad\\'chars'"); + })); + }); + test("encoding can be specified by config", function() { var config = { client_encoding: "utf-8"