1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat: warn when using --allow-run with no allow list (#25215)

This commit is contained in:
David Sherret 2024-09-17 00:08:02 +01:00 committed by GitHub
parent f7ddea3af7
commit b0525edd6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 46 additions and 11 deletions

View file

@ -809,6 +809,8 @@ impl CliOptions {
} }
} }
warn_insecure_allow_run_flags(&flags);
let maybe_lockfile = maybe_lockfile.filter(|_| !force_global_cache); let maybe_lockfile = maybe_lockfile.filter(|_| !force_global_cache);
let deno_dir_provider = let deno_dir_provider =
Arc::new(DenoDirProvider::new(flags.cache_path.clone())); Arc::new(DenoDirProvider::new(flags.cache_path.clone()));
@ -1688,6 +1690,27 @@ impl CliOptions {
} }
} }
/// Warns for specific uses of `--allow-run`. This function is not
/// intended to catch every single possible insecure use of `--allow-run`,
/// but is just an attempt to discourage some common pitfalls.
fn warn_insecure_allow_run_flags(flags: &Flags) {
let permissions = &flags.permissions;
if permissions.allow_all {
return;
}
let Some(allow_run_list) = permissions.allow_run.as_ref() else {
return;
};
// discourage using --allow-run without an allow list
if allow_run_list.is_empty() {
log::warn!(
"{} --allow-run can be trivially exploited. Prefer specifying an allow list (https://docs.deno.com/runtime/fundamentals/security/#running-subprocesses)",
colors::yellow("Warning")
);
}
}
/// Resolves the path to use for a local node_modules folder. /// Resolves the path to use for a local node_modules folder.
fn resolve_node_modules_folder( fn resolve_node_modules_folder(
cwd: &Path, cwd: &Path,

View file

@ -17,9 +17,7 @@ if (import.meta.main) {
"--config", "--config",
Deno.realPathSync("../config/deno.json"), Deno.realPathSync("../config/deno.json"),
"--no-lock", "--no-lock",
"--allow-read", "-A",
"--allow-run",
"--allow-ffi",
"--unstable-ffi", "--unstable-ffi",
import.meta.url, import.meta.url,
], ],

View file

@ -1,3 +1,4 @@
Warning --allow-run can be trivially exploited. Prefer specifying an allow list (https://docs.deno.com/runtime/fundamentals/security/#running-subprocesses)
NotCapable: Requires run access to "deno", run again with the --allow-run flag NotCapable: Requires run access to "deno", run again with the --allow-run flag
at [WILDCARD] { at [WILDCARD] {
name: "NotCapable" name: "NotCapable"

View file

@ -1,10 +1,10 @@
Running... Running...
NotCapable: Requires run access to "deno", run again with the --allow-run flag NotCapable: Requires run access to "binary", run again with the --allow-run flag
[WILDCARD] [WILDCARD]
at file:///[WILDLINE]/sub.ts:15:5 { at file:///[WILDLINE]/sub.ts:15:5 {
name: "NotCapable" name: "NotCapable"
} }
NotCapable: Requires run access to "deno", run again with the --allow-run flag NotCapable: Requires run access to "binary", run again with the --allow-run flag
[WILDCARD] [WILDCARD]
at file:///[WILDLINE]/sub.ts:23:22 { at file:///[WILDLINE]/sub.ts:23:22 {
name: "NotCapable" name: "NotCapable"

View file

@ -1,4 +1,4 @@
const binaryName = Deno.build.os === "windows" ? "deno.exe" : "deno"; const binaryName = Deno.build.os === "windows" ? "binary.exe" : "binary";
Deno.copyFileSync(Deno.execPath(), binaryName); Deno.copyFileSync(Deno.execPath(), binaryName);
console.log("Running..."); console.log("Running...");
@ -9,9 +9,12 @@ new Deno.Command(
"run", "run",
"--allow-write", "--allow-write",
"--allow-read", "--allow-read",
`--allow-run=deno`, `--allow-run=binary`,
"sub.ts", "sub.ts",
], ],
env: {
PATH: Deno.cwd(),
},
stderr: "inherit", stderr: "inherit",
stdout: "inherit", stdout: "inherit",
}, },

View file

@ -1,4 +1,4 @@
const binaryName = Deno.build.os === "windows" ? "deno.exe" : "deno"; const binaryName = Deno.build.os === "windows" ? "binary.exe" : "binary";
const pathSep = Deno.build.os === "windows" ? "\\" : "/"; const pathSep = Deno.build.os === "windows" ? "\\" : "/";
Deno.mkdirSync("subdir"); Deno.mkdirSync("subdir");
@ -6,7 +6,7 @@ Deno.copyFileSync(binaryName, "subdir/" + binaryName);
try { try {
const commandResult = new Deno.Command( const commandResult = new Deno.Command(
"deno", "binary",
{ {
env: { "PATH": Deno.cwd() + pathSep + "subdir" }, env: { "PATH": Deno.cwd() + pathSep + "subdir" },
stdout: "inherit", stdout: "inherit",
@ -22,7 +22,7 @@ try {
try { try {
const child = Deno.run( const child = Deno.run(
{ {
cmd: ["deno"], cmd: ["binary"],
env: { "PATH": Deno.cwd() + pathSep + "subdir" }, env: { "PATH": Deno.cwd() + pathSep + "subdir" },
stdout: "inherit", stdout: "inherit",
stderr: "inherit", stderr: "inherit",

View file

@ -0,0 +1,8 @@
{
"tests": {
"no_allow_list": {
"args": "run --allow-run main.ts",
"output": "no_allow_list.out"
}
}
}

View file

@ -0,0 +1 @@
Warning --allow-run can be trivially exploited. Prefer specifying an allow list (https://docs.deno.com/runtime/fundamentals/security/#running-subprocesses)

View file

@ -1,5 +1,5 @@
{ {
"args": "test --allow-run --allow-read captured_output.ts", "args": "test -A captured_output.ts",
"output": "main.out", "output": "main.out",
"envs": { "NO_COLOR": "1" }, "envs": { "NO_COLOR": "1" },
"exitCode": 0 "exitCode": 0

View file

@ -1,3 +1,4 @@
Warning --allow-run can be trivially exploited. Prefer specifying an allow list (https://docs.deno.com/runtime/fundamentals/security/#running-subprocesses)
PermissionStatus { state: "granted", onchange: null, partial: true } PermissionStatus { state: "granted", onchange: null, partial: true }
PermissionStatus { state: "denied", onchange: null } PermissionStatus { state: "denied", onchange: null }
PermissionStatus { state: "granted", onchange: null } PermissionStatus { state: "granted", onchange: null }