CVE-2023-35931 (published 2023-06-23T20:15Z)

Shescape is a simple shell escape library for JavaScript. An attacker may be able to get read-only access to environment variables. This bug has been patched in version 1.7.1.\n\n\n

CVSS v3 base score: 4.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-526
cwe_name: Cleartext Storage of Sensitive Information in an Environment Variable
description: The product uses an environment variable to store unencrypted sensitive information.
extended_description: Information stored in an environment variable can be accessible by other processes with the execution context, including child processes that dependencies are executed in, or serverless functions in cloud environments. An environment variable's contents can also be inserted into messages, headers, log files, or other outputs. Often these other dependencies have no need to use the environment variable in question. A weakness that discloses environment variables could expose this information.
         

Fix information:
repo_url: https://github.com/ericcornelissen/shescape
commit_details: repo_url: https://github.com/ericcornelissen/shescape
author: Eric Cornelissen
author_date: 2023-06-21 20:31:29+02:00
msg: Test coverage for environment variables (#982)

Add e2e test coverage for environment variables and add escaping of `%`
for CMD. ALso include `%` in test fixtures for all shells on Windows.

The new test cases for environment variables are also included in the
`shescape/testing` injectionStrings.
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,9 @@ Versioning].
 
 ## [Unreleased]
 
+- Add `%` escaping for CMD. ([#982])
 - Correct documented behavior of quoting functions. ([#969])
+- Expand injection strings to cover environment variables. ([#982])
 
 ## [1.7.0] - 2023-06-12
 
@@ -260,6 +262,7 @@ Versioning].
 [#909]: https://github.com/ericcornelissen/shescape/pull/909
 [#936]: https://github.com/ericcornelissen/shescape/pull/936
 [#969]: https://github.com/ericcornelissen/shescape/pull/969
+[#982]: https://github.com/ericcornelissen/shescape/pull/982
 [552e8ea]: https://github.com/ericcornelissen/shescape/commit/552e8eab56861720b1d4e5474fb65741643358f9
 [keep a changelog]: https://keepachangelog.com/en/1.0.0/
 [semantic versioning]: https://semver.org/spec/v2.0.0.html

programming_language: Markdown
filename: cmd.js
change_type: ModificationType.MODIFY
diff: @@ -14,7 +14,7 @@ function escapeArgForInterpolation(arg) {
     .replace(/[\0\u0008\u001B\u009B]/gu, "")
     .replace(/\r?\n|\r/gu, " ")
     .replace(/\^/gu, "^^")
-    .replace(/(["&<>|])/gu, "^$1");
+    .replace(/(["%&<>|])/gu, "^$1");
 }
 
 /**
@@ -53,6 +53,7 @@ function escapeArgForQuoted(arg) {
   return arg
     .replace(/[\0\u0008\u001B\u009B]/gu, "")
     .replace(/\r?\n|\r/gu, " ")
+    .replace(/%/gu, "^%")
     .replace(/"/gu, `""`);
 }
 

programming_language: JavaScript
filename: win.js
change_type: ModificationType.MODIFY
diff: @@ -854,6 +854,16 @@ export const escape = {
         expected: { interpolation: "a$b$c", noInterpolation: "a$b$c" },
       },
     ],
+    "percentage signs ('%')": [
+      {
+        input: "a%b",
+        expected: { interpolation: "a^%b", noInterpolation: "a%b" },
+      },
+      {
+        input: "a%b%c",
+        expected: { interpolation: "a^%b^%c", noInterpolation: "a%b%c" },
+      },
+    ],
     "ampersands ('&')": [
       {
         input: "a&b",
@@ -2010,6 +2020,16 @@ export const escape = {
         expected: { interpolation: "a`$b`$c", noInterpolation: "a`$b`$c" },
       },
     ],
+    "percentage signs ('%')": [
+      {
+        input: "a%b",
+        expected: { interpolation: "a%b", noInterpolation: "a%b" },
+      },
+      {
+        input: "a%b%c",
+        expected: { interpolation: "a%b%c", noInterpolation: "a%b%c" },
+      },
+    ],
     "ampersands ('&')": [
       {
         input: "a&b",
@@ -2949,6 +2969,16 @@ export const quote = {
         expected: '"a$b$c"',
       },
     ],
+    "percentage signs ('%')": [
+      {
+        input: "a%b",
+        expected: '"a^%b"',
+      },
+      {
+        input: "a%b%c",
+        expected: '"a^%b^%c"',
+      },
+    ],
     "left double quotation mark ('“')": [
       {
         input: "a“b",
@@ -3147,6 +3177,16 @@ export const quote = {
         expected: '"a`$b`$c"',
       },
     ],
+    "percentage signs ('%')": [
+      {
+        input: "a%b",
+        expected: '"a%b"',
+      },
+      {
+        input: "a%b%c",
+        expected: '"a%b%c"',
+      },
+    ],
     "left double quotation mark ('“')": [
       {
         input: "a“b",

programming_language: TypeScript
filename: _common.cjs
change_type: ModificationType.MODIFY
diff: @@ -49,11 +49,12 @@ function isShellPowerShell(shell) {
  *
  * @param {object} args The function arguments.
  * @param {string} args.arg The input argument that was echoed.
+ * @param {boolean} args.quoted Was `arg` quoted prior to echoing.
  * @param {string} args.shell The shell used for echoing.
  * @param {boolean} normalizeWhitespace Whether whitespace should be normalized.
  * @returns {string} The expected echoed value.
  */
-function getExpectedOutput({ arg, shell }, normalizeWhitespace) {
+function getExpectedOutput({ arg, quoted, shell }, normalizeWhitespace) {
   // Remove control characters, like Shescape
   arg = arg.replace(/[\0\u0008\u001B\u009B]/gu, "");
 
@@ -64,6 +65,11 @@ function getExpectedOutput({ arg, shell }, normalizeWhitespace) {
     arg = arg.replace(/\r(?!\n)/gu, "");
   }
 
+  // Adjust % for shell when quoted
+  if (isShellCmd(shell) && quoted) {
+    arg = arg.replace(/%/gu, "^%");
+  }
+
   if (normalizeWhitespace) {
     // Replace newline characters, like Shescape
     if (!isShellCmd(shell)) {

programming_language: JavaScript
filename: testing.js
change_type: ModificationType.MODIFY
diff: @@ -15,7 +15,15 @@ import { checkedToString, toArrayIfNecessary } from "./src/reflection.js";
  *   assert.equal(result, "no injection");
  * }
  */
-export const injectionStrings = ["\x00world", "&& ls", "'; ls #", '"; ls #'];
+export const injectionStrings = [
+  "\x00world",
+  "&& ls",
+  "'; ls #",
+  '"; ls #',
+  "$PATH",
+  "$Env:PATH",
+  "%PATH%",
+];
 
 /**
  * A test stub of shescape that has the same input-output profile as the real

programming_language: TypeScript