Low severityNVD Advisory· Published Jun 23, 2023· Updated Dec 5, 2024
Shescape potential environment variable exposure on Windows with CMD
CVE-2023-35931
Description
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.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
shescapenpm | < 1.7.1 | 1.7.1 |
Affected products
1- Range: < 1.7.1
Patches
1d0fce70f987aTest coverage for environment variables (#982)
5 files changed · +61 −3
CHANGELOG.md+3 −0 modified@@ -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
src/win/cmd.js+2 −1 modified@@ -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, `""`); }
test/fixtures/win.js+40 −0 modified@@ -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",
test/fuzz/_common.cjs+7 −1 modified@@ -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)) {
testing.js+9 −1 modified@@ -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
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-3g7p-8qhx-mc8rghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-35931ghsaADVISORY
- github.com/ericcornelissen/shescape/commit/d0fce70f987ac0d8331f93cb45d47e79436173acghsax_refsource_MISCWEB
- github.com/ericcornelissen/shescape/pull/982ghsax_refsource_MISCWEB
- github.com/ericcornelissen/shescape/releases/tag/v1.7.1ghsax_refsource_MISCWEB
- github.com/ericcornelissen/shescape/security/advisories/GHSA-3g7p-8qhx-mc8rghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.