mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 17:59:08 +00:00
fix(audit): skip env option arguments when reading a Node shebang
This commit is contained in:
2 files changed
+43
-3
No files matched your search
@@ -3068,6 +3068,11 @@ describe("ReleaseExposureReader Node shebang scripts", () => {
|
||||
["#!/usr/bin/env node"],
|
||||
["#!/usr/bin/env node\r"],
|
||||
["#!/usr/bin/env -S node --no-warnings"],
|
||||
["#!/usr/bin/env -S -u NODE_OPTIONS node"],
|
||||
["#!/usr/bin/env -u NODE_OPTIONS node"],
|
||||
["#!/usr/bin/env -C /srv/app node"],
|
||||
["#!/usr/bin/env -Snode --no-warnings"],
|
||||
["#!/usr/bin/env --unset NODE_OPTIONS -- node"],
|
||||
["#!/usr/local/bin/node --no-warnings"],
|
||||
["#! /usr/bin/nodejs"],
|
||||
])("reads the map of %j in a directory", async (shebang) => {
|
||||
|
||||
@@ -1308,12 +1308,47 @@ const hasNodeShebang = (prefix: Buffer): boolean => {
|
||||
const [line = ""] = prefix.toString("latin1", 2).split("\n", 1);
|
||||
const [interpreter = "", ...args] = line.trim().split(/[ \t]+/u);
|
||||
const program =
|
||||
basename(interpreter) === "env"
|
||||
? args.find((arg) => !arg.startsWith("-") && !arg.includes("="))
|
||||
: interpreter;
|
||||
basename(interpreter) === "env" ? envProgram(args) : interpreter;
|
||||
return program !== undefined && /^node(?:js)?$/u.test(basename(program));
|
||||
};
|
||||
|
||||
/** `env` options whose argument is the next field, as in `-u NODE_OPTIONS`. */
|
||||
const ENV_OPTION_WITH_ARGUMENT = new Set([
|
||||
"-u",
|
||||
"--unset",
|
||||
"-C",
|
||||
"--chdir",
|
||||
"-P",
|
||||
]);
|
||||
|
||||
/**
|
||||
* The program an `env` shebang runs: the first field that is neither an
|
||||
* option, an option's argument, nor a `NAME=value` setting. `-S` splits the
|
||||
* rest of the line, so its attached text is read as the next fields.
|
||||
*/
|
||||
const envProgram = (args: string[]): string | undefined => {
|
||||
const fields = [...args];
|
||||
while (fields.length > 0) {
|
||||
const field = fields.shift() ?? "";
|
||||
if (field === "--") return fields[0];
|
||||
if (ENV_OPTION_WITH_ARGUMENT.has(field)) {
|
||||
fields.shift();
|
||||
continue;
|
||||
}
|
||||
if (/^-[0iv]*S./u.test(field)) {
|
||||
fields.unshift(field.slice(field.indexOf("S") + 1));
|
||||
continue;
|
||||
}
|
||||
if (field.startsWith("--split-string=")) {
|
||||
fields.unshift(field.slice("--split-string=".length));
|
||||
continue;
|
||||
}
|
||||
if (field.startsWith("-") || field.includes("=")) continue;
|
||||
return field;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* A name is not a format: a package member called `payload.json` or
|
||||
* `payload.js.map` can be a PE or an ASAR, and a script or map declaration
|
||||
|
||||
Reference in new issue
Block a user