CVE-2023-34232 (published 2023-06-08T21:15Z)

snowflake-connector-nodejs, a NodeJS driver for Snowflake, is vulnerable to command injection via single sign on (SSO) browser URL authentication in versions prior to 1.6.21. In order to exploit the potential for command injection, an attacker would need to be successful in (1) establishing a malicious resource and (2) redirecting users to utilize the resource. The attacker could set up a malicious, publicly accessible server which responds to the SSO URL with an attack payload. If the attacker then tricked a user into visiting the maliciously crafted connection URL, the user’s local machine would render the malicious payload, leading to a remote code execution. This attack scenario can be mitigated through URL whitelisting as well as common anti-phishing resources. Version 1.6.21 contains a patch for this issue.

CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-77
cwe_name: Improper Neutralization of Special Elements used in a Command ('Command Injection')
description: The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.
extended_description: 
            Many protocols and products have their own custom command language. While OS or shell command strings are frequently discovered and targeted, developers may not realize that these other command languages might also be vulnerable to attacks.
         
         

Fix information:
repo_url: https://github.com/snowflakedb/snowflake-connector-nodejs
commit_details: repo_url: https://github.com/snowflakedb/snowflake-connector-nodejs
author: sfc-gh-ext-simba-lf
author_date: 2023-04-17 11:11:20-07:00
msg: Replace eval() for parsing JSON strings (#465)

* Replace eval() with JSON.parse() for parsing JSON strings

* Replace eval with safe-eval for parsing JSON strings

* Replace eval with better-eval for parsing JSON strings

* Use assert without strict for comparing objects created by better-eval

* Use assert without strict for comparing objects created by better-eval

* Use assert without strict for comparing objects created by better-eval

---------

Co-authored-by: ilesh garish <111810784+sfc-gh-igarish@users.noreply.github.com>
repository: repo_url: https://github.com/snowflakedb/snowflake-connector-nodejs
repo_name: snowflakedb/snowflake-connector-nodejs
description: NodeJS driver
repo_language: JavaScript
owner: snowflakedb
file_changes: filename: column.js
change_type: ModificationType.MODIFY
diff: @@ -9,6 +9,7 @@ var SfTimestamp = require('./sf_timestamp');
 var SqlTypes = require('./data_types').SqlTypes;
 var bigInt = require('big-integer');
 var { XMLParser, XMLValidator } = require("fast-xml-parser");
+var betterEval = require("better-eval");
 
 var NULL_UPPERCASE = 'NULL';
 
@@ -551,7 +552,7 @@ function convertRawVariant(rawColumnValue, column, context)
   {
     try
     {
-      ret = eval("(" + rawColumnValue + ")");
+      ret = betterEval("(" + rawColumnValue + ")");
     }
     catch (parseError)
     {

programming_language: JavaScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -11,6 +11,7 @@
 	"async": "^3.2.3",
     "aws-sdk": "^2.878.0",
     "axios": "^0.27.2",
+    "better-eval": "^1.3.0",
     "big-integer": "^1.6.43",
     "bignumber.js": "^2.4.0",
     "binascii": "0.0.2",

programming_language: JavaScript
filename: testDataType.js
change_type: ModificationType.MODIFY
diff: @@ -234,7 +234,10 @@ describe('Test DataType', function ()
               connection,
               selectVariant,
               [{'COLA': {a: 1, b: [1, 2, 3, -Infinity, undefined], c: {a: 1}}}],
-              callback
+              callback,
+              null,
+              true,
+              false
             );
           }],
         done
@@ -259,7 +262,10 @@ describe('Test DataType', function ()
               connection,
               selectArray,
               [{'COLA': ['a', 1]}],
-              callback
+              callback,
+              null,
+              true,
+              false
             );
           }],
         done

programming_language: JavaScript
filename: testUtil.js
change_type: ModificationType.MODIFY
diff: @@ -51,10 +51,11 @@ module.exports.checkError = function (err)
   assert.ok(!err, JSON.stringify(err));
 };
 
-module.exports.executeQueryAndVerify = function (connection, sql, expected, callback, bindArray, normalize)
+module.exports.executeQueryAndVerify = function (connection, sql, expected, callback, bindArray, normalize, strict)
 {
   // Sometimes we may not want to normalize the row first
   normalize = (typeof normalize !== "undefined" && normalize != null) ? normalize : true;
+  strict = (typeof strict !== "undefined" && strict != null) ? strict : true;
   var executeOptions = {};
   executeOptions.sqlText = sql;
   executeOptions.complete = function (err, stmt)
@@ -67,7 +68,14 @@ module.exports.executeQueryAndVerify = function (connection, sql, expected, call
       var row;
       while ((row = stream.read()) !== null)
       {
-        assert.deepStrictEqual(normalize ? normalizeRowObject(row) : row, expected[rowCount]);
+        if (strict)
+        {
+          assert.deepStrictEqual(normalize ? normalizeRowObject(row) : row, expected[rowCount]);
+        }
+        else
+        {
+          assert.deepEqual(normalize ? normalizeRowObject(row) : row, expected[rowCount]);
+        }
         rowCount++;
       }
     });

programming_language: JavaScript
filename: result_test_variant.js
change_type: ModificationType.MODIFY
diff: @@ -59,18 +59,18 @@ describe('Result: test variant', function ()
         function (row)
         {
           // variant
-          assert.deepStrictEqual(row.getColumnValue('C1'), {a: 1});
-          assert.strictEqual(
+          assert.deepEqual(row.getColumnValue('C1'), {a: 1});
+          assert.equal(
             row.getColumnValueAsString('C1'), JSON.stringify({a: 1}));
 
           // object
-          assert.deepStrictEqual(row.getColumnValue('C2'), {a: 1});
-          assert.strictEqual(
+          assert.deepEqual(row.getColumnValue('C2'), {a: 1});
+          assert.equal(
             row.getColumnValueAsString('C2'), JSON.stringify({a: 1}));
 
           // array
-          assert.deepStrictEqual(row.getColumnValue('C3'), [1, 2]);
-          assert.strictEqual(
+          assert.deepEqual(row.getColumnValue('C3'), [1, 2]);
+          assert.equal(
             row.getColumnValueAsString('C3'), JSON.stringify([1, 2]));
         },
         function (result)

programming_language: JavaScript