CVE-2024-21511 (published 2024-04-23T05:15Z)

Versions of the package mysql2 before 3.9.7 are vulnerable to Arbitrary Code Injection due to improper sanitization of the timezone parameter in the readCodeFor function by calling a native MySQL Server date/time function.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/sidorares/node-mysql2
commit_details: repo_url: https://github.com/sidorares/node-mysql2
author: Andrey Sidorov
author_date: 2024-04-21 20:59:27+10:00
msg: fix(security): sanitize timezone parameter value to prevent code injection (#2608)

* fix(security): sanitize timezone parameter value to prevent code injection. Discovered by zhaoyudi (Nebulalab）
repository: repo_url: https://github.com/sidorares/node-mysql2
repo_name: sidorares/node-mysql2
description: :zap: fast mysqljs/mysql compatible mysql driver for node.js
repo_language: JavaScript
owner: sidorares
file_changes: filename: binary_parser.js
change_type: ModificationType.MODIFY
diff: @@ -42,9 +42,9 @@ function readCodeFor(field, config, options, fieldNum) {
     case Types.TIMESTAMP:
     case Types.NEWDATE:
       if (helpers.typeMatch(field.columnType, dateStrings, Types)) {
-        return `packet.readDateTimeString(${field.decimals});`;
+        return `packet.readDateTimeString(${parseInt(field.decimals, 10)});`;
       }
-      return `packet.readDateTime('${timezone}');`;
+      return `packet.readDateTime(${helpers.srcEscape(timezone)});`;
     case Types.TIME:
       return 'packet.readTimeString()';
     case Types.DECIMAL:

programming_language: JavaScript
filename: text_parser.js
change_type: ModificationType.MODIFY
diff: @@ -48,13 +48,13 @@ function readCodeFor(type, charset, encodingExpr, config, options) {
       if (helpers.typeMatch(type, dateStrings, Types)) {
         return 'packet.readLengthCodedString("ascii")';
       }
-      return `packet.parseDate('${timezone}')`;
+      return `packet.parseDate(${helpers.srcEscape(timezone)})`;
     case Types.DATETIME:
     case Types.TIMESTAMP:
       if (helpers.typeMatch(type, dateStrings, Types)) {
         return 'packet.readLengthCodedString("ascii")';
       }
-      return `packet.parseDateTime('${timezone}')`;
+      return `packet.parseDateTime(${helpers.srcEscape(timezone)})`;
     case Types.TIME:
       return 'packet.readLengthCodedString("ascii")';
     case Types.GEOMETRY:

programming_language: JavaScript
filename: timezone-binary-sanitization.test.mjs
change_type: ModificationType.ADD
diff: @@ -0,0 +1,24 @@
+import { describe, test, assert } from 'poku';
+import { createConnection, describeOptions } from '../../../common.test.cjs';
+
+const connection = createConnection().promise();
+
+describe('Binary Parser: timezone Sanitization', describeOptions);
+
+Promise.all([
+  test(async () => {
+    process.env.TEST_ENV_VALUE = 'secure';
+    await connection.execute({
+      sql: 'SELECT NOW()',
+      timezone: `'); process.env.TEST_ENV_VALUE = "not so much"; //`,
+    });
+
+    assert.strictEqual(
+      process.env.TEST_ENV_VALUE,
+      'secure',
+      'Timezone sanitization failed - code injection possible',
+    );
+  }),
+]).then(async () => {
+  await connection.end();
+});

programming_language: TypeScript
filename: timezone-text-sanitization.test.mjs
change_type: ModificationType.ADD
diff: @@ -0,0 +1,24 @@
+import { describe, test, assert } from 'poku';
+import { createConnection, describeOptions } from '../../../common.test.cjs';
+
+const connection = createConnection().promise();
+
+describe('Text Parser: timezone Sanitization', describeOptions);
+
+Promise.all([
+  test(async () => {
+    process.env.TEST_ENV_VALUE = 'secure';
+    await connection.query({
+      sql: 'SELECT NOW()',
+      timezone: `'); process.env.TEST_ENV_VALUE = "not so much"; //`,
+    });
+
+    assert.strictEqual(
+      process.env.TEST_ENV_VALUE,
+      'secure',
+      'Timezone sanitization failed - code injection possible',
+    );
+  }),
+]).then(async () => {
+  await connection.end();
+});

programming_language: TypeScript