CVE-2022-0944: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: Template injection in connection test endpoint leads to RCE in GitHub repository sqlpad/sqlpad prior to 6.10.1.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 7.2
Published: 2022-03-15T01:15Z
Repository: https://github.com/sqlpad/sqlpad
Language: JSON
Files changed: server/lib/render-connection.js, server/package-lock.json, server/package.json
Commit date: 2022-03-13 19:55:40 -0500
Commit message: Use mustache to process connection template (#1110)


Diff: diff --git a/server/lib/render-connection.js b/server/lib/render-connection.js
index d91ccb51..9dd926e0 100644
--- a/server/lib/render-connection.js
+++ b/server/lib/render-connection.js
@@ -1,6 +1,11 @@
-const _ = require('lodash');
+const mustache = require('mustache');
+
+// Disable HTML escaping. We're not using it for HTML
+mustache.escape = function (text) {
+  return text;
+};
 
 /**
  * Iterates over connection object, replacing any template strings with values from user
  * This allows dynamic values inserted based on logged in user
  * This uses a mustache-like syntax, using double mustaches.
@@ -17,13 +22,11 @@ function renderConnection(connection, user) {
       const value = renderConnection(connection.data, user);
       connection.data = value;
     } else {
       const value = connection[key];
       if (typeof value === 'string') {
-        _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
-        const compiled = _.template(value);
-        replaced[key] = compiled({ user });
+        replaced[key] = mustache.render(value, { user });
       } else {
         replaced[key] = value;
       }
     }
   });
diff --git a/server/package-lock.json b/server/package-lock.json
index b8239313..b2bf813a 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -4095,10 +4095,15 @@
         "rfdc": "^1.3.0",
         "tarn": "^3.0.2",
         "tedious": "^14.0.0"
       }
     },
+    "mustache": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
+      "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="
+    },
     "mysql": {
       "version": "2.18.1",
       "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
       "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
       "requires": {
diff --git a/server/package.json b/server/package.json
index 57786198..8b0b74a0 100644
--- a/server/package.json
+++ b/server/package.json
@@ -67,10 +67,11 @@
     "memorystore": "^1.6.7",
     "minimist": "^1.2.5",
     "mkdirp": "^1.0.4",
     "moment": "^2.29.1",
     "mssql": "^8.0.2",
+    "mustache": "^4.2.0",
     "mysql": "^2.18.1",
     "mysql2": "^2.3.3",
     "node-crate": "^2.0.6",
     "node-fetch": "^2.6.7",
     "node-xlsx": "^0.21.0",

Vulnerable code: const _ = require('lodash');
        _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
        const compiled = _.template(value);
        replaced[key] = compiled({ user });
Fixed code: const mustache = require('mustache');

// Disable HTML escaping. We're not using it for HTML
mustache.escape = function (text) {
  return text;
};
        replaced[key] = mustache.render(value, { user });
    "mustache": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
      "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="
    },
    "mustache": "^4.2.0",