CVE-2021-21384 (published 2021-03-19T00:15Z)

shescape is a simple shell escape package for JavaScript. In shescape before version 1.1.3, anyone using _Shescape_ to defend against shell injection may still be vulnerable against shell injection if the attacker manages to insert a into the payload. For an example see the referenced GitHub Security Advisory. The problem has been patched in version 1.1.3. No further changes are required.

Severity: MEDIUM
CVSS v2 base score: 4.6 (AV:L/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.8, HIGH (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-88
cwe_name: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')
description: The product constructs a string for a command to be executed by a separate component
in another control sphere, but it does not properly delimit the
intended arguments, options, or switches within that command string.
extended_description: 
            When creating commands using interpolation into a string, developers may assume that only the arguments/options that they specify will be processed.  This assumption may be even stronger when the programmer has encoded the command in a way that prevents separate commands from being provided maliciously, e.g. in the case of shell metacharacters.  When constructing the command, the developer may use whitespace or other delimiters that are required to separate arguments when the command. However, if an attacker can provide an untrusted input that contains argument-separating delimiters, then the resulting command will have more arguments than intended by the developer.  The attacker may then be able to change the behavior of the command.  Depending on the functionality supported by the extraneous arguments, this may have security-relevant consequences.
         
         

Fix information:
repo_url: https://github.com/ericcornelissen/shescape
commit_details: repo_url: https://github.com/ericcornelissen/shescape
author: Eric Cornelissen
author_date: 2021-03-13 18:14:10+01:00
msg: Strip null characters from arguments

Update both the Unix and Windows `escapeShellArg` implementation to
strip null characters from input. Null characters can be used to at
least cause errors and potentially execute arbitrary commands (depending
on the shell).

This bug was found due to the new fuzzing logic.
repository: repo_url: https://github.com/ericcornelissen/shescape
repo_name: ericcornelissen/shescape
description: Simple shell escape library for JavaScript
repo_language: JavaScript
owner: ericcornelissen
file_changes: filename: CHANGELOG.md
change_type: ModificationType.MODIFY
diff: @@ -7,7 +7,7 @@ Versioning].
 
 ## [Unreleased]
 
-- _No changes yet_
+- Strip null characters from arguments.
 
 ## [1.1.2] - 2021-01-07
 

programming_language: Markdown
filename: unix.js
change_type: ModificationType.MODIFY
diff: @@ -11,7 +11,7 @@
  * @returns {string} The escaped argument.
  */
 function escapeShellArg(arg) {
-  return arg.replace(/'/g, `'\\''`);
+  return arg.replace(/\u{0}/gu, "").replace(/'/g, `'\\''`);
 }
 
 module.exports.escapeShellArg = escapeShellArg;

programming_language: TypeScript
filename: win.js
change_type: ModificationType.MODIFY
diff: @@ -11,7 +11,7 @@
  * @returns {string} The escaped argument.
  */
 function escapeShellArg(arg) {
-  return arg.replace(/"/g, `""`);
+  return arg.replace(/\u{0}/gu, "").replace(/"/g, `""`);
 }
 
 module.exports.escapeShellArg = escapeShellArg;

programming_language: JavaScript
filename: unix.test.js
change_type: ModificationType.MODIFY
diff: @@ -22,4 +22,20 @@ describe("unix.js", function () {
       assert.strictEqual(output, `'\\'' & echo '\\''Hello world!'\\''`);
     });
   });
+
+  describe("null characters", function () {
+    const nullChar = String.fromCharCode(0);
+
+    it("removes one null character", function () {
+      const input = `foo' && ls${nullChar} -al ; echo 'bar`;
+      const output = escapeShellArg(input);
+      assert.strictEqual(output, `foo'\\'' && ls -al ; echo '\\''bar`);
+    });
+
+    it("removes multiple null character", function () {
+      const input = `foo'${nullChar}&&ls -al${nullChar};echo 'bar`;
+      const output = escapeShellArg(input);
+      assert.strictEqual(output, `foo'\\''&&ls -al;echo '\\''bar`);
+    });
+  });
 });

programming_language: JavaScript
filename: win.test.js
change_type: ModificationType.MODIFY
diff: @@ -22,4 +22,20 @@ describe("win.js", function () {
       assert.strictEqual(output, `"" & echo ""Hello world!`);
     });
   });
+
+  describe("null characters", function () {
+    const nullChar = String.fromCharCode(0);
+
+    it("removes one null character", function () {
+      const input = `foo" && ls${nullChar} -al ; echo "bar`;
+      const output = escapeShellArg(input);
+      assert.strictEqual(output, `foo"" && ls -al ; echo ""bar`);
+    });
+
+    it("removes multiple null character", function () {
+      const input = `foo"${nullChar}&&ls -al${nullChar};echo "bar`;
+      const output = escapeShellArg(input);
+      assert.strictEqual(output, `foo""&&ls -al;echo ""bar`);
+    });
+  });
 });

programming_language: JavaScript